IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
IKVM.Runtime.RuntimeManagedJavaType Class Referencesealed

Implements a RuntimeJavaType that exposes existing managed .NET types not the result of static compilation. More...

Classes

class  AttributeAnnotationJavaTypeBase
 
class  EnumValueJavaField
 
class  FakeJavaType
 

Protected Member Functions

override void LazyPublishMembers ()
 

Detailed Description

Implements a RuntimeJavaType that exposes existing managed .NET types not the result of static compilation.

Definition at line 37 of file RuntimeManagedJavaType.ValueTypeDefaultCtorJavaMethod.cs.

Member Function Documentation

◆ LazyPublishMembers()

override void IKVM.Runtime.RuntimeManagedJavaType.LazyPublishMembers ( )
protected

Definition at line 334 of file RuntimeManagedJavaType.cs.

335 {
336 // special support for enums
337 if (type.IsEnum)
338 {
339 Type underlyingType = EnumHelper.GetUnderlyingType(type);
340 Type javaUnderlyingType;
341 if (underlyingType == Context.Types.SByte)
342 {
343 javaUnderlyingType = Context.Types.Byte;
344 }
345 else if (underlyingType == Context.Types.UInt16)
346 {
347 javaUnderlyingType = Context.Types.Int16;
348 }
349 else if (underlyingType == Context.Types.UInt32)
350 {
351 javaUnderlyingType = Context.Types.Int32;
352 }
353 else if (underlyingType == Context.Types.UInt64)
354 {
355 javaUnderlyingType = Context.Types.Int64;
356 }
357 else
358 {
359 javaUnderlyingType = underlyingType;
360 }
361
362 var fieldType = Context.ClassLoaderFactory.GetJavaTypeFromType(javaUnderlyingType);
363 var fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static);
364 var fieldsList = new List<RuntimeJavaField>();
365 for (int i = 0; i < fields.Length; i++)
366 {
367 if (fields[i].FieldType == type)
368 {
369 var name = fields[i].Name;
370 if (name == "Value")
371 name = "_Value";
372 else if (name.StartsWith("_") && name.EndsWith("Value"))
373 name = "_" + name;
374
375 var val = EnumHelper.GetPrimitiveValue(Context, underlyingType, fields[i].GetRawConstantValue());
376 fieldsList.Add(new RuntimeConstantJavaField(this, fieldType, name, fieldType.SigName, Modifiers.Public | Modifiers.Static | Modifiers.Final, fields[i], val, MemberFlags.None));
377 }
378 }
379 fieldsList.Add(new EnumValueJavaField(this, fieldType));
380 SetFields(fieldsList.ToArray());
381 SetMethods(new RuntimeJavaMethod[] { new EnumWrapJavaMethod(this, fieldType) });
382 }
383 else
384 {
385 var fieldsList = new List<RuntimeJavaField>();
386 var fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
387 for (int i = 0; i < fields.Length; i++)
388 {
389 // TODO for remapped types, instance fields need to be converted to static getter/setter methods
390 if (fields[i].FieldType.IsPointer)
391 {
392 // skip, pointer fields are not supported
393 }
394 else
395 {
396 // TODO handle name/signature clash
397 fieldsList.Add(CreateFieldWrapperDotNet(Context.AttributeHelper.GetModifiers(fields[i], true).Modifiers, fields[i].Name, fields[i].FieldType, fields[i]));
398 }
399 }
400 SetFields(fieldsList.ToArray());
401
402 var methodsList = new Dictionary<string, RuntimeJavaMethod>();
403
404 // special case for delegate constructors!
405 if (IsDelegate(Context, type))
406 {
407 var iface = InnerClasses[0];
408 var mw = new DelegateJavaMethod(this, (DelegateInnerClassJavaType)iface);
409 methodsList.Add(mw.Name + mw.Signature, mw);
410 }
411
412 // add a protected default constructor to MulticastDelegate to make it easier to define a delegate in Java
413 if (type == Context.Types.MulticastDelegate)
414 methodsList.Add("<init>()V", new MulticastDelegateCtorJavaMethod(this));
415
416 var constructors = type.GetConstructors(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
417 for (int i = 0; i < constructors.Length; i++)
418 {
419 if (MakeMethodDescriptor(constructors[i], out var name, out var sig, out var args, out var ret))
420 {
421 var mw = CreateMethodWrapper(name, sig, args, ret, constructors[i], false);
422 var key = mw.Name + mw.Signature;
423 if (methodsList.ContainsKey(key) == false)
424 methodsList.Add(key, mw);
425 }
426 }
427
428 if (type.IsValueType && !methodsList.ContainsKey("<init>()V"))
429 {
430 // Value types have an implicit default ctor
431 methodsList.Add("<init>()V", new ValueTypeDefaultCtorJavaMethod(this));
432 }
433
434 var methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
435 for (int i = 0; i < methods.Length; i++)
436 {
437 if (methods[i].IsStatic && type.IsInterface)
438 {
439 // skip, Java cannot deal with static methods on interfaces
440 }
441 else
442 {
443 if (MakeMethodDescriptor(methods[i], out var name, out var sig, out var args, out var ret))
444 {
445 if (!methods[i].IsStatic && !methods[i].IsPrivate && BaseTypeWrapper != null)
446 {
447 var baseMethod = BaseTypeWrapper.GetMethod(name, sig, true);
448 if (baseMethod != null && baseMethod.IsFinal && !baseMethod.IsStatic && !baseMethod.IsPrivate)
449 continue;
450 }
451
452 var mw = CreateMethodWrapper(name, sig, args, ret, methods[i], false);
453 var key = mw.Name + mw.Signature;
454 methodsList.TryGetValue(key, out var existing);
455
456 if (existing == null || existing is ByRefJavaMethod)
457 methodsList[key] = mw;
458 }
459 else if (methods[i].IsAbstract)
460 {
461 SetHasUnsupportedAbstractMethods();
462 }
463 }
464 }
465
466 // make sure that all the interface methods that we implement are available as public methods,
467 // otherwise javac won't like the class.
468 if (!type.IsInterface)
469 {
470 var interfaces = type.GetInterfaces();
471 for (int i = 0; i < interfaces.Length; i++)
472 {
473 // we only handle public (or nested public) types, because we're potentially adding a
474 // method that should be callable by anyone through the interface
475 if (interfaces[i].IsVisible)
476 {
477 if (Context.ClassLoaderFactory.IsRemappedType(interfaces[i]))
478 {
479 var tw = Context.ClassLoaderFactory.GetJavaTypeFromType(interfaces[i]);
480 foreach (var mw in tw.GetMethods())
481 {
482 // HACK we need to link here, because during a core library build we might reference java.lang.AutoCloseable (via IDisposable) before it has been linked
483 mw.Link();
484 InterfaceMethodStubHelper(methodsList, mw.GetMethod(), mw.Name, mw.Signature, mw.GetParameters(), mw.ReturnType);
485 }
486 }
487
488 var map = type.GetInterfaceMap(interfaces[i]);
489 for (int j = 0; j < map.InterfaceMethods.Length; j++)
490 {
491 if (map.TargetMethods[j] == null || ((!map.TargetMethods[j].IsPublic || map.TargetMethods[j].Name != map.InterfaceMethods[j].Name) && map.TargetMethods[j].DeclaringType == type))
492 {
493 if (MakeMethodDescriptor(map.InterfaceMethods[j], out var name, out var sig, out var args, out var ret))
494 {
495 InterfaceMethodStubHelper(methodsList, map.InterfaceMethods[j], name, sig, args, ret);
496 }
497 }
498 }
499 }
500 }
501 }
502
503 // for non-final remapped types, we need to add all the virtual methods in our alter ego (which
504 // appears as our base class) and make them final (to prevent Java code from overriding these
505 // methods, which don't really exist).
506 if (Context.ClassLoaderFactory.IsRemappedType(type) && !type.IsSealed && !type.IsInterface)
507 {
508 var baseTypeWrapper = BaseTypeWrapper;
509
510 while (baseTypeWrapper != null)
511 {
512 foreach (var m in baseTypeWrapper.GetMethods())
513 {
514 if (!m.IsStatic && !m.IsFinal && (m.IsPublic || m.IsProtected) && m.Name != "<init>")
515 {
516 var key = m.Name + m.Signature;
517 if (!methodsList.ContainsKey(key))
518 {
519 if (m.IsProtected)
520 {
521 if (m.Name == "finalize" && m.Signature == "()V")
522 {
523 methodsList.Add(key, new FinalizeJavaMethod(this));
524 }
525 else if (m.Name == "clone" && m.Signature == "()Ljava.lang.Object;")
526 {
527 methodsList.Add(key, new CloneJavaMethod(this));
528 }
529 else
530 {
531 // there should be a special MethodWrapper for this method
532 throw new InvalidOperationException("Missing protected method support for " + baseTypeWrapper.Name + "::" + m.Name + m.Signature);
533 }
534 }
535 else
536 {
537 methodsList.Add(key, new BaseFinalJavaMethod(this, m));
538 }
539 }
540 }
541 }
542
543 baseTypeWrapper = baseTypeWrapper.BaseTypeWrapper;
544 }
545 }
546
547#if !IMPORTER && !EXPORTER && !FIRST_PASS
548
549 // support serializing .NET exceptions (by replacing them with a placeholder exception)
550 if (typeof(Exception).IsAssignableFrom(type) && !typeof(java.io.Serializable.__Interface).IsAssignableFrom(type) && !methodsList.ContainsKey("writeReplace()Ljava.lang.Object;"))
551 {
552 methodsList.Add("writeReplace()Ljava.lang.Object;", new ExceptionWriteReplaceJavaMethod(this));
553 }
554
555#endif
556
557 var methodArray = new RuntimeJavaMethod[methodsList.Count];
558 methodsList.Values.CopyTo(methodArray, 0);
559 SetMethods(methodArray);
560 }
561 }
IKVM.Reflection.Type Type
AttributeHelper AttributeHelper
Gets the AttributeHelper associated with this instance of the runtime.
Types Types
Gets the Types associated with this instance of the runtime.
RuntimeClassLoaderFactory ClassLoaderFactory
Gets the RuntimeClassLoaderFactory associated with this instance of the runtime.
Type MulticastDelegate
Definition Types.cs:109
MemberFlags
Describes various options applied to a member.

The documentation for this class was generated from the following files: