Skip to content

Commit 6ec5995

Browse files
jonpryorradekdoulik
authored andcommitted
[Java.Interop] Begin API review of "full" Java.Interop.dll
`make xa-fxcop` ran Gendarme against the `XAIntegrationDebug` version of `Java.Interop.dll`. Add a `make fxcop` target which runs Gendarme on the full assembly. Rename `xa-gendarme-ignore.txt` to `gendarme-ignore.txt`, and ignore rules and/or update source code in order to remove all of the **Severity: High** errors that Gendarme reports. Finally, split out the `Java.Interop.GenericMarshaler` namespace into a new `Java.Interop.GenericMarshaler.dll` assembly, as this is functionality we won't want required in `Java.Interop.dll` when we use the "full" profile with Xamarin.Android.
1 parent 5eeb287 commit 6ec5995

17 files changed

+6023
-4691
lines changed

Java.Interop.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Android.Cecil", "sr
9797
EndProject
9898
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Android.Cecil.Mdb", "src\Xamarin.Android.Cecil\Xamarin.Android.Cecil.Mdb.csproj", "{C0487169-8F81-497F-919E-EB42B1D0243F}"
9999
EndProject
100+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Java.Interop.GenericMarshaler", "src\Java.Interop.GenericMarshaler\Java.Interop.GenericMarshaler.csproj", "{D1243BAB-23CA-4566-A2A3-3ADA2C2DC3AF}"
101+
EndProject
100102
Global
101103
GlobalSection(SolutionConfigurationPlatforms) = preSolution
102104
Debug|Any CPU = Debug|Any CPU
@@ -335,6 +337,10 @@ Global
335337
{C0487169-8F81-497F-919E-EB42B1D0243F}.XAIntegrationDebug|Any CPU.Build.0 = Debug|Any CPU
336338
{C0487169-8F81-497F-919E-EB42B1D0243F}.XAIntegrationRelease|Any CPU.ActiveCfg = Release|Any CPU
337339
{C0487169-8F81-497F-919E-EB42B1D0243F}.XAIntegrationRelease|Any CPU.Build.0 = Release|Any CPU
340+
{D1243BAB-23CA-4566-A2A3-3ADA2C2DC3AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
341+
{D1243BAB-23CA-4566-A2A3-3ADA2C2DC3AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
342+
{D1243BAB-23CA-4566-A2A3-3ADA2C2DC3AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
343+
{D1243BAB-23CA-4566-A2A3-3ADA2C2DC3AF}.Release|Any CPU.Build.0 = Release|Any CPU
338344
EndGlobalSection
339345
GlobalSection(NestedProjects) = preSolution
340346
{0C001D50-4176-45AE-BDC8-BA626508B0CC} = {C8F58966-94BF-407F-914A-8654F8B8AE3B}
@@ -377,5 +383,6 @@ Global
377383
{58B564A1-570D-4DA2-B02D-25BDDB1A9F4F} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
378384
{15945D4B-FF56-4BCC-B598-2718D199DD08} = {C8F58966-94BF-407F-914A-8654F8B8AE3B}
379385
{C0487169-8F81-497F-919E-EB42B1D0243F} = {C8F58966-94BF-407F-914A-8654F8B8AE3B}
386+
{D1243BAB-23CA-4566-A2A3-3ADA2C2DC3AF} = {4C173212-371D-45D8-BA83-9226194F48DC}
380387
EndGlobalSection
381388
EndGlobal

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,10 @@ src/Java.Runtime.Environment/Java.Runtime.Environment.dll.config: src/Java.Runti
7373
sed 's#@JI_JVM_PATH@#$(JI_JVM_PATH)#g' < $< > $@
7474

7575
xa-fxcop: lib/gendarme-2.10/gendarme.exe bin/$(XA_CONFIGURATION)/Java.Interop.dll
76-
$(RUNTIME) $< --html xa-gendarme.html $(if @(GENDARME_XML),--xml xa-gendarme.xml) --ignore xa-gendarme-ignore.txt bin/$(XA_CONFIGURATION)/Java.Interop.dll
76+
$(RUNTIME) $< --html xa-gendarme.html $(if @(GENDARME_XML),--xml xa-gendarme.xml) --ignore gendarme-ignore.txt bin/$(XA_CONFIGURATION)/Java.Interop.dll
77+
78+
fxcop: lib/gendarme-2.10/gendarme.exe bin/$(CONFIGURATION)/Java.Interop.dll
79+
$(RUNTIME) $< --html gendarme.html $(if @(GENDARME_XML),--xml gendarme.xml) --ignore gendarme-ignore.txt bin/$(CONFIGURATION)/Java.Interop.dll
7780

7881
lib/gendarme-2.10/gendarme.exe:
7982
-mkdir -p `dirname "$@"`

xa-gendarme-ignore.txt renamed to gendarme-ignore.txt

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
R: Gendarme.Rules.BadPractice.ConstructorShouldNotCallVirtualMethodsRule
2+
# We're attempting to establish a pattern/protocol around JavaObject + JniPeerMembers, and I hereby deem it acceptable -- in this instance -- to invoke the virtual `JniPeerMembers` property from constructors
3+
M: System.Void Java.Interop.JavaException::.ctor()
4+
M: System.Void Java.Interop.JavaException::.ctor(System.String)
5+
M: System.Void Java.Interop.JavaException::.ctor(System.String,System.Exception)
6+
M: System.Void Java.Interop.JavaObject::.ctor()
7+
18
R: Gendarme.Rules.BadPractice.OnlyUseDisposeForIDisposableTypesRule
29
# We need *a* "cleanup" method, and I can't think of a better name than "Dispose"
310
# (Close? Destroy?), and for these types I don't want them to have Dispose()
@@ -16,6 +23,10 @@ R: Gendarme.Rules.BadPractice.PreferSafeHandleRule
1623
T: Java.Interop.JniEnvironmentInfo
1724
T: Java.Interop.JniRuntime
1825

26+
R: Gendarme.Rules.Correctness.AvoidFloatingPointEqualityRule
27+
# This is in from generated code. We could plausibly fix the generated code, but I'm not at all sure what to change it *to*.
28+
M: System.Int32 Java.Interop.JavaSingleArray::IndexOf(System.Single)
29+
M: System.Int32 Java.Interop.JavaDoubleArray::IndexOf(System.Double)
1930

2031
R: Gendarme.Rules.Correctness.CheckParametersNullityInVisibleMethodsRule
2132
# These methods are protected, and thus we control the (public) callers,
@@ -27,12 +38,29 @@ M: Java.Interop.JniPeerMembers Java.Interop.JniPeerMembers::GetPeerMembers(Java.
2738
# I suspect a gendarme bug; I don't see what it's talking about
2839
M: System.Void Java.Interop.JniArgumentValue::.ctor(Java.Interop.IJavaPeerable)
2940

30-
3141
R: Gendarme.Rules.Correctness.EnsureLocalDisposalRule
3242
# We don't *want* to dispose the value!
43+
M: Java.Interop.JniType Java.Interop.JniBoolean::get_TypeRef()
44+
M: Java.Interop.JniType Java.Interop.JniByte::get_TypeRef()
45+
M: Java.Interop.JniType Java.Interop.JniCharacter::get_TypeRef()
46+
M: Java.Interop.JniType Java.Interop.JniDouble::get_TypeRef()
47+
M: System.Void Java.Interop.JniEnvironment/Exceptions::Throw(System.Exception)
3348
M: System.Void Java.Interop.JniEnvironmentInfo::set_EnvironmentPointer(System.IntPtr)
49+
M: Java.Interop.JniType Java.Interop.JniFloat::get_TypeRef()
50+
M: Java.Interop.JniType Java.Interop.JniInteger::get_TypeRef()
51+
M: Java.Interop.JniType Java.Interop.JniLong::get_TypeRef()
3452
M: Java.Interop.JniType Java.Interop.JniPeerMembers::get_JniPeerType()
3553
M: Java.Interop.JniRuntime Java.Interop.JniRuntime::get_CurrentRuntime()
54+
M: System.Void Java.Interop.JniRuntime::RaisePendingException(System.Exception)
55+
M: System.Void Java.Interop.JniRuntime/JniValueManager::DisposeUnlessReferenced(Java.Interop.IJavaPeerable)
56+
M: System.Object Java.Interop.JniRuntime/JniValueManager::PeekValue(Java.Interop.JniObjectReference)
57+
M: System.Object Java.Interop.JniRuntime/JniValueManager::PeekBoxedObject(Java.Interop.JniObjectReference)
58+
M: Java.Interop.JniType Java.Interop.JniShort::get_TypeRef()
59+
M: Java.Interop.JniType Java.Interop.JniSystem::get_TypeRef()
60+
M: System.Void Java.Interop.ManagedPeer::Construct(System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr)
61+
M: System.Void Java.Interop.ManagedPeer::RegisterNativeMembers(System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr)
62+
M: System.Object Java.Interop.ProxyValueMarshaler::CreateGenericValue(Java.Interop.JniObjectReference&,Java.Interop.JniObjectReferenceOptions,System.Type)
63+
M: Java.Interop.JniValueMarshalerState Java.Interop.ProxyValueMarshaler::CreateGenericObjectReferenceArgumentState(System.Object,System.Reflection.ParameterAttributes)
3664

3765
# These look like gendarme bugs wrt C#2 `yield return` methods.
3866
M: System.Collections.IEnumerator Java.Interop.JniRuntime/JniTypeManager/<CreateGetTypeSignaturesEnumerator>c__Iterator0::System.Collections.IEnumerable.GetEnumerator()
@@ -43,6 +71,9 @@ M: System.Collections.IEnumerator Java.Interop.JniRuntime/JniTypeManager/<Create
4371
R: Gendarme.Rules.Correctness.ReviewInconsistentIdentityRule
4472
# It's consistent; GetHashCode()'s use of QualifiedReference pulls in everything Equals() compares.
4573
T: Java.Interop.JniTypeSignature
74+
# It's consistent; everything is delegated to Java!
75+
T: Java.Interop.JavaException
76+
T: Java.Interop.JavaObject
4677

4778

4879
R: Gendarme.Rules.Design.AvoidRefAndOutParametersRule
@@ -104,6 +135,7 @@ T: Java.Interop.JniRuntime/JniTypeManager
104135

105136
R: Gendarme.Rules.Design.DisposableTypesShouldHaveFinalizerRule
106137
# No, not all IDisposable types should have finalizers.
138+
T: Java.Interop.JniArrayElements
107139
T: Java.Interop.JniEnvironmentInfo
108140

109141
R: Gendarme.Rules.Design.EnumsShouldUseInt32Rule
@@ -161,10 +193,20 @@ R: Gendarme.Rules.Design.Generic.AvoidDeclaringCustomDelegatesRule
161193
T: Java.Interop.DestroyJavaVMDelegate
162194
T: Java.Interop.DetachCurrentThreadDelegate
163195

196+
R: Gendarme.Rules.Design.Generic.DoNotExposeNestedGenericSignaturesRule
197+
M: System.Linq.Expressions.Expression`1<System.Func`4<System.Reflection.ConstructorInfo,Java.Interop.JniObjectReference,System.Object[],System.Object>> Java.Interop.JniRuntime/JniMarshalMemberBuilder::CreateConstructActivationPeerExpression(System.Reflection.ConstructorInfo)
164198

165199
R: Gendarme.Rules.Exceptions.DoNotSwallowErrorsCatchingNonSpecificExceptionsRule
166200
M: System.Reflection.Assembly Java.Interop.JniRuntime/JniTypeManager::TryLoadAssembly(System.Reflection.AssemblyName)
167201

202+
R: Gendarme.Rules.Exceptions.ExceptionShouldBeVisibleRule
203+
T: Java.Interop.JniLocationException
204+
205+
R: Gendarme.Rules.Exceptions.MissingExceptionConstructorsRule
206+
# System.Runtime.Serialization.SerializationInfo doesn't exist in our targeted PCL profile, so we can't provide the (SerializationInfo, StreamingContext) constructor.
207+
T: Java.Interop.JavaException
208+
T: Java.Interop.JavaProxyThrowable
209+
T: Java.Interop.JniLocationException
168210

169211
R: Gendarme.Rules.Exceptions.UseObjectDisposedExceptionRule
170212
# I don't want ~any overhead around reference tracking
@@ -181,6 +223,12 @@ M: System.IntPtr Java.Interop.JniRuntime/JniObjectReferenceManager::ReleaseLocal
181223
# These *do* validate, they just validate via AssertValid() helper method
182224
M: System.Void Java.Interop.JniRuntime::AttachCurrentThread(System.String,Java.Interop.JniObjectReference)
183225
M: System.Void Java.Interop.JniRuntime::DestroyRuntime()
226+
M: System.Void Java.Interop.JniRuntime/JniTypeManager::OnSetRuntime(Java.Interop.JniRuntime)
227+
M: Java.Interop.JniTypeSignature Java.Interop.JniRuntime/JniTypeManager::GetTypeSignature(System.Type)
228+
M: System.Collections.Generic.IEnumerable`1<Java.Interop.JniTypeSignature> Java.Interop.JniRuntime/JniTypeManager::GetTypeSignatures(System.Type)
229+
M: System.Type Java.Interop.JniRuntime/JniTypeManager::GetType(Java.Interop.JniTypeSignature)
230+
M: System.Collections.Generic.IEnumerable`1<System.Type> Java.Interop.JniRuntime/JniTypeManager::GetTypes(Java.Interop.JniTypeSignature)
231+
M: System.Void Java.Interop.JniRuntime/JniTypeManager::RegisterNativeMembers(Java.Interop.JniType,System.Type,System.String)
184232
M: Java.Interop.JniType Java.Interop.JniType::GetSuperclass()
185233
M: System.Boolean Java.Interop.JniType::IsAssignableFrom(Java.Interop.JniType)
186234
M: System.Boolean Java.Interop.JniType::IsInstanceOfType(Java.Interop.JniObjectReference)
@@ -219,6 +267,7 @@ M: System.IntPtr Java.Interop.NativeMethods::java_interop_jnienv_get_primitive_a
219267
R: Gendarme.Rules.Maintainability.AvoidAlwaysNullFieldRule
220268
# I suspect that this is a Roslyn bug; mcs output doesn't produce this.
221269
T: Java.Interop.JniRuntime/JniTypeManager/<CreateGetTypesForSimpleReferenceEnumerator>d__15
270+
T: Java.Interop.JniRuntime/JniTypeManager/<CreateGetTypesForSimpleReferenceEnumerator>d__19
222271

223272

224273
R: Gendarme.Rules.Maintainability.AvoidLackOfCohesionOfMethodsRule
@@ -484,6 +533,13 @@ M: Java.Interop.JniObjectReference Java.Interop.JniEnvironment/Reflection::ToRef
484533
M: Java.Interop.JniObjectReference Java.Interop.JniEnvironment/Reflection::ToReflectedField(Java.Interop.JniObjectReference,Java.Interop.JniFieldInfo,System.Boolean)
485534
M: Java.Interop.JniObjectReferenceFlags Java.Interop.JniObjectReference::get_Flags()
486535

536+
# I think Gendarme is buggy here; `JavaArray<T>.CheckLength(IList<T>)` *is* used.
537+
M: System.Int32 Java.Interop.JavaArray`1::CheckLength(System.Collections.Generic.IList`1<T>)
538+
539+
# `__RegisterNativeMembers()` is invoked via Reflection
540+
M: System.Void Java.Interop.JavaProxyObject::__RegisterNativeMembers(Java.Interop.JniType,System.String)
541+
M: System.Void Java.Interop.JavaProxyThrowable::__RegisterNativeMembers(Java.Interop.JniType,System.String)
542+
487543
# We need JNIEnv::FindClass() to be *bound* so that the JavaInterop_FindClass() wrapper is emitted.
488544
# We don't want to actually *use* it, so it's `internal` and unused. Ignore
489545
M: Java.Interop.JniObjectReference Java.Interop.JniEnvironment/Types::_FindClass(System.String)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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>8.0.30703</ProductVersion>
7+
<SchemaVersion>2.0</SchemaVersion>
8+
<ProjectGuid>{D1243BAB-23CA-4566-A2A3-3ADA2C2DC3AF}</ProjectGuid>
9+
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
10+
<OutputType>Library</OutputType>
11+
<RootNamespace>Java.Interop.GenericMarshaler</RootNamespace>
12+
<AssemblyName>Java.Interop.GenericMarshaler</AssemblyName>
13+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
14+
<TargetFrameworkProfile>Profile111</TargetFrameworkProfile>
15+
<SignAssembly>true</SignAssembly>
16+
<AssemblyOriginatorKeyFile>..\..\product.snk</AssemblyOriginatorKeyFile>
17+
</PropertyGroup>
18+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
19+
<DebugSymbols>true</DebugSymbols>
20+
<DebugType>full</DebugType>
21+
<Optimize>false</Optimize>
22+
<OutputPath>..\..\bin\Debug</OutputPath>
23+
<DefineConstants>DEBUG;</DefineConstants>
24+
<ErrorReport>prompt</ErrorReport>
25+
<WarningLevel>4</WarningLevel>
26+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
27+
</PropertyGroup>
28+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
29+
<Optimize>true</Optimize>
30+
<OutputPath>..\..\bin\Release</OutputPath>
31+
<ErrorReport>prompt</ErrorReport>
32+
<WarningLevel>4</WarningLevel>
33+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
34+
</PropertyGroup>
35+
<ItemGroup>
36+
<Compile Include="Properties\AssemblyInfo.cs" />
37+
<Compile Include="Java.Interop.GenericMarshaler\JniPeerInstanceMethodsExtensions.cs">
38+
<DependentUpon>Java.Interop.GenericMarshaler\JniPeerInstanceMethodsExtensions.tt</DependentUpon>
39+
</Compile>
40+
</ItemGroup>
41+
<ItemGroup>
42+
<None Include="Java.Interop.GenericMarshaler\JniPeerInstanceMethodsExtensions.tt">
43+
<Generator>TextTemplatingFileGenerator</Generator>
44+
<LastGenOutput>Java.Interop.GenericMarshaler\JniPeerInstanceMethodsExtensions.cs</LastGenOutput>
45+
</None>
46+
</ItemGroup>
47+
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
48+
<ItemGroup>
49+
<ProjectReference Include="..\Java.Interop\Java.Interop.csproj">
50+
<Project>{94BD81F7-B06F-4295-9636-F8A3B6BDC762}</Project>
51+
<Name>Java.Interop</Name>
52+
</ProjectReference>
53+
</ItemGroup>
54+
</Project>

0 commit comments

Comments
 (0)