[vm, lib] Teach mirrors about the Never type and member signatures.

Bug: https://github.com/dart-lang/sdk/issues/12478
Bug: https://github.com/dart-lang/sdk/issues/40497
Bug: https://github.com/dart-lang/sdk/issues/40510
Change-Id: I841d7e239b8235555ec26fbcb74ca41b5de60f58
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134806
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Ryan Macnak 2020-02-07 20:57:46 +00:00
parent 05b806ace7
commit a73b0ceda2
12 changed files with 65 additions and 24 deletions

View file

@ -22,6 +22,10 @@ used (see Issue [39627][]).
options. Previously setting a socket options would be ignored and getting a
socket option would return `null`.
#### `dart:mirrors`
* Added `MirrorSystem.neverType`.
### Dart VM
### Tools

View file

@ -272,7 +272,7 @@ static RawInstance* CreateMethodMirror(const Function& func,
<< Mirrors::kFactoryCtor);
kind_flags |=
(static_cast<intptr_t>(func.is_external()) << Mirrors::kExternal);
bool is_synthetic = func.is_no_such_method_forwarder();
bool is_synthetic = func.is_synthetic();
kind_flags |= (static_cast<intptr_t>(is_synthetic) << Mirrors::kSynthetic);
kind_flags |= (static_cast<intptr_t>(func.is_extension_member())
<< Mirrors::kExtensionMember);
@ -311,7 +311,9 @@ static RawInstance* CreateClassMirror(const Class& cls,
ASSERT(ref_type.IsCanonical());
return CreateClassMirror(cls, ref_type, is_declaration, owner_mirror);
}
ASSERT(!cls.IsDynamicClass() && !cls.IsVoidClass());
ASSERT(!cls.IsDynamicClass());
ASSERT(!cls.IsVoidClass());
ASSERT(!cls.IsNeverClass());
ASSERT(!type.IsNull());
ASSERT(type.IsFinalized());
@ -625,6 +627,10 @@ static RawInstance* CreateTypeMirror(const AbstractType& type) {
Array& args = Array::Handle(Array::New(1));
args.SetAt(0, Symbols::Dynamic());
return CreateMirror(Symbols::_SpecialTypeMirror(), args);
} else if (cls.IsNeverClass()) {
Array& args = Array::Handle(Array::New(1));
args.SetAt(0, Symbols::Never());
return CreateMirror(Symbols::_SpecialTypeMirror(), args);
}
// TODO(regis): Until mirrors reflect nullability, force kLegacy, except for
// Null type, which should remain nullable.
@ -830,7 +836,8 @@ DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 0, 1) {
ASSERT(type.HasTypeClass());
const Class& cls = Class::Handle(type.type_class());
ASSERT(!cls.IsNull());
if (cls.IsDynamicClass() || cls.IsVoidClass() || cls.IsTypedefClass()) {
if (cls.IsDynamicClass() || cls.IsVoidClass() || cls.IsNeverClass() ||
cls.IsTypedefClass()) {
Exceptions::ThrowArgumentError(type);
UNREACHABLE();
}
@ -1172,8 +1179,7 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_members, 0, 2) {
entry = entries.GetNext();
if (entry.IsClass()) {
const Class& klass = Class::Cast(entry);
// We filter out dynamic.
// TODO(12478): Should not need to filter out dynamic.
ASSERT(!klass.IsVoidClass() && !klass.IsNeverClass());
if (!klass.IsDynamicClass()) {
error = klass.EnsureIsFinalized(thread);
if (!error.IsNull()) {
@ -1700,6 +1706,8 @@ DEFINE_NATIVE_ENTRY(DeclarationMirror_location, 0, 1) {
ASSERT(!script.IsNull());
const String& uri = String::Handle(zone, script.url());
return CreateSourceLocation(uri, 1, 1);
} else {
FATAL1("Unexpected declaration type: %s", decl.ToCString());
}
ASSERT(!script.IsNull());

View file

@ -2261,8 +2261,7 @@ void BytecodeReaderHelper::ReadFunctionDeclarations(const Class& cls) {
function.set_is_declared_in_bytecode(true);
function.set_has_pragma(has_pragma);
function.set_end_token_pos(end_position);
function.set_is_no_such_method_forwarder(
(flags & kIsNoSuchMethodForwarderFlag) != 0);
function.set_is_synthetic((flags & kIsNoSuchMethodForwarderFlag) != 0);
function.set_is_reflectable((flags & kIsReflectableFlag) != 0);
function.set_is_debuggable((flags & kIsDebuggableFlag) != 0);
function.set_is_extension_member(is_extension_member);

View file

@ -545,6 +545,7 @@ class ProcedureHelper {
kRedirectingFactoryConstructor = 1 << 6,
kNoSuchMethodForwarder = 1 << 7,
kExtensionMember = 1 << 8,
kMemberSignature = 1 << 9,
};
explicit ProcedureHelper(KernelReaderHelper* helper)
@ -571,6 +572,7 @@ class ProcedureHelper {
return (flags_ & kNoSuchMethodForwarder) != 0;
}
bool IsExtensionMember() const { return (flags_ & kExtensionMember) != 0; }
bool IsMemberSignature() const { return (flags_ & kMemberSignature) != 0; }
NameIndex canonical_name_;
TokenPosition start_position_;

View file

@ -1917,8 +1917,8 @@ void KernelLoader::LoadProcedure(const Library& library,
script_class, procedure_helper.start_position_));
function.set_has_pragma(has_pragma_annotation);
function.set_end_token_pos(procedure_helper.end_position_);
function.set_is_no_such_method_forwarder(
procedure_helper.IsNoSuchMethodForwarder());
function.set_is_synthetic(procedure_helper.IsNoSuchMethodForwarder() ||
procedure_helper.IsMemberSignature());
if (register_function) {
functions_.Add(&function);
} else {

View file

@ -7892,7 +7892,7 @@ RawFunction* Function::New(const String& name,
result.set_is_generated_body(false);
result.set_has_pragma(false);
result.set_is_polymorphic_target(false);
result.set_is_no_such_method_forwarder(false);
result.set_is_synthetic(false);
NOT_IN_PRECOMPILED(result.set_state_bits(0));
result.set_owner(owner);
NOT_IN_PRECOMPILED(result.set_token_pos(token_pos));

View file

@ -3395,7 +3395,7 @@ class Function : public Object {
V(GeneratedBody, is_generated_body) \
V(PolymorphicTarget, is_polymorphic_target) \
V(HasPragma, has_pragma) \
V(IsNoSuchMethodForwarder, is_no_such_method_forwarder) \
V(IsSynthetic, is_synthetic) \
V(IsExtensionMember, is_extension_member)
#define DEFINE_ACCESSORS(name, accessor_name) \

View file

@ -105,7 +105,7 @@ bool SourceReport::ShouldSkipFunction(const Function& func) {
return true;
}
if (func.is_abstract() || func.IsImplicitConstructor() ||
func.IsRedirectingFactory() || func.is_no_such_method_forwarder()) {
func.IsRedirectingFactory() || func.is_synthetic()) {
return true;
}
// Note that context_scope() remains null for closures declared in bytecode,

View file

@ -84,6 +84,7 @@ bool _subtypeTest(Type a, Type b) native 'TypeMirror_subtypeTest';
class _MirrorSystem extends MirrorSystem {
final TypeMirror dynamicType = new _SpecialTypeMirror._('dynamic');
final TypeMirror voidType = new _SpecialTypeMirror._('void');
final TypeMirror neverType = new _SpecialTypeMirror._('Never');
var _libraries;
Map<Uri, LibraryMirror> get libraries {
@ -685,13 +686,15 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror {
bool isSubtypeOf(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
if (other == currentMirrorSystem().voidType) return true;
if (other == currentMirrorSystem().neverType) return false;
return _subtypeTest(_reflectedType, (other as _TypeMirror)._reflectedType);
}
bool isAssignableTo(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
if (other == currentMirrorSystem().voidType) return true;
if (other == currentMirrorSystem().neverType) return false;
final otherReflectedType = (other as _TypeMirror)._reflectedType;
return _subtypeTest(_reflectedType, otherReflectedType) ||
_subtypeTest(otherReflectedType, _reflectedType);
@ -893,13 +896,15 @@ class _TypeVariableMirror extends _DeclarationMirror
bool isSubtypeOf(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
if (other == currentMirrorSystem().voidType) return true;
if (other == currentMirrorSystem().neverType) return false;
return _subtypeTest(_reflectedType, (other as _TypeMirror)._reflectedType);
}
bool isAssignableTo(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
if (other == currentMirrorSystem().voidType) return true;
if (other == currentMirrorSystem().neverType) return false;
final otherReflectedType = (other as _TypeMirror)._reflectedType;
return _subtypeTest(_reflectedType, otherReflectedType) ||
_subtypeTest(otherReflectedType, _reflectedType);
@ -995,13 +1000,15 @@ class _TypedefMirror extends _DeclarationMirror
bool isSubtypeOf(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
if (other == currentMirrorSystem().voidType) return true;
if (other == currentMirrorSystem().neverType) return false;
return _subtypeTest(_reflectedType, (other as _TypeMirror)._reflectedType);
}
bool isAssignableTo(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
if (other == currentMirrorSystem().voidType) return true;
if (other == currentMirrorSystem().neverType) return false;
final otherReflectedType = (other as _TypeMirror)._reflectedType;
return _subtypeTest(_reflectedType, otherReflectedType) ||
_subtypeTest(otherReflectedType, _reflectedType);

View file

@ -60,6 +60,7 @@
library dart.mirrors;
import 'dart:async' show Future;
import "dart:_internal" show Since;
/**
* A [MirrorSystem] is the main interface used to reflect on a set of
@ -110,6 +111,12 @@ abstract class MirrorSystem {
*/
TypeMirror get voidType;
/**
* A mirror on the [:Never:] type.
*/
@Since("2.8")
TypeMirror get neverType;
/**
* Returns the name of [symbol].
*

View file

@ -82,6 +82,7 @@ bool _subtypeTest(Type a, Type b) native 'TypeMirror_subtypeTest';
class _MirrorSystem extends MirrorSystem {
final TypeMirror dynamicType = new _SpecialTypeMirror._('dynamic');
final TypeMirror voidType = new _SpecialTypeMirror._('void');
final TypeMirror neverType = new _SpecialTypeMirror._('Never');
var _libraries;
Map<Uri, LibraryMirror> get libraries {
@ -682,13 +683,15 @@ class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror {
bool isSubtypeOf(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
if (other == currentMirrorSystem().voidType) return true;
if (other == currentMirrorSystem().neverType) return false;
return _subtypeTest(_reflectedType, (other as _TypeMirror)._reflectedType);
}
bool isAssignableTo(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
if (other == currentMirrorSystem().voidType) return true;
if (other == currentMirrorSystem().neverType) return false;
final otherReflectedType = (other as _TypeMirror)._reflectedType;
return _subtypeTest(_reflectedType, otherReflectedType) ||
_subtypeTest(otherReflectedType, _reflectedType);
@ -890,13 +893,15 @@ class _TypeVariableMirror extends _DeclarationMirror
bool isSubtypeOf(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
if (other == currentMirrorSystem().voidType) return true;
if (other == currentMirrorSystem().neverType) return false;
return _subtypeTest(_reflectedType, (other as _TypeMirror)._reflectedType);
}
bool isAssignableTo(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
if (other == currentMirrorSystem().voidType) return true;
if (other == currentMirrorSystem().neverType) return false;
final otherReflectedType = (other as _TypeMirror)._reflectedType;
return _subtypeTest(_reflectedType, otherReflectedType) ||
_subtypeTest(otherReflectedType, _reflectedType);
@ -992,13 +997,15 @@ class _TypedefMirror extends _DeclarationMirror
bool isSubtypeOf(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
if (other == currentMirrorSystem().voidType) return true;
if (other == currentMirrorSystem().neverType) return false;
return _subtypeTest(_reflectedType, (other as _TypeMirror)._reflectedType);
}
bool isAssignableTo(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
if (other == currentMirrorSystem().voidType) return true;
if (other == currentMirrorSystem().neverType) return false;
final otherReflectedType = (other as _TypeMirror)._reflectedType;
return _subtypeTest(_reflectedType, otherReflectedType) ||
_subtypeTest(otherReflectedType, _reflectedType);

View file

@ -58,6 +58,7 @@
library dart.mirrors;
import 'dart:async' show Future;
import "dart:_internal" show Since;
/**
* A [MirrorSystem] is the main interface used to reflect on a set of
@ -108,6 +109,12 @@ abstract class MirrorSystem {
*/
TypeMirror get voidType;
/**
* A mirror on the [:Never:] type.
*/
@Since("2.8")
TypeMirror get neverType;
/**
* Returns the name of [symbol].
*