Properly resolve top-level setters

Fixes issue 4386.

When converting a getter to a setter (converting a right-hand
side expression to a left-hand side, assignable entity),
we need to know where to look for the setter function.
Top-level setters need to be resolved in the library or prefix
scope in which the getter was found.

R=regis@google.com

Review URL: https://codereview.chromium.org//1090373006

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@45316 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
hausner@google.com 2015-04-21 17:36:34 +00:00
parent 667173800b
commit 21ca62f8bc
15 changed files with 251 additions and 68 deletions

View file

@ -561,34 +561,116 @@ AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) {
AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
if (is_super_getter()) {
ASSERT(receiver() != NULL);
// If the static setter is not found in the superclass, noSuchMethod will be
// called at runtime.
const String& setter_name =
String::ZoneHandle(Field::SetterSymbol(field_name_));
Function& setter = Function::ZoneHandle(
Resolver::ResolveDynamicAnyArgs(cls(), setter_name));
if (setter.IsNull() || setter.is_abstract()) {
// No instance setter found in super class chain,
// noSuchMethod will be called at runtime.
return new StaticSetterNode(token_pos(),
receiver(),
cls(),
field_name_,
rhs);
}
return new StaticSetterNode(token_pos(),
receiver(),
cls(),
field_name(),
field_name_,
setter,
rhs);
}
if (owner().IsLibraryPrefix()) {
const LibraryPrefix& prefix = LibraryPrefix::Cast(owner_);
// The parser has already dealt with the pathological case where a
// library imports itself. See Parser::ResolveIdentInPrefixScope()
ASSERT(field_name_.CharAt(0) != Library::kPrivateIdentifierStart);
// If the prefix is not yet loaded, the getter doesn't exist. Return a
// setter that will throw a NSME at runtime.
if (!prefix.is_loaded()) {
return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs);
}
Object& obj = Object::Handle(prefix.LookupObject(field_name_));
if (obj.IsField()) {
const Field& field = Field::ZoneHandle(Field::Cast(obj).raw());
if (!field.is_final()) {
if (Isolate::Current()->TypeChecksEnabled()) {
rhs = new AssignableNode(field.token_pos(),
rhs,
AbstractType::ZoneHandle(field.type()),
field_name_);
}
return new StoreStaticFieldNode(token_pos(), field, rhs);
}
}
// No field found in prefix. Look for a setter function.
const String& setter_name = String::Handle(Field::SetterName(field_name_));
obj = prefix.LookupObject(setter_name);
if (obj.IsFunction()) {
const Function& setter = Function::ZoneHandle(Function::Cast(obj).raw());
ASSERT(setter.is_static() && setter.IsSetterFunction());
return new StaticSetterNode(
token_pos(), NULL, field_name_, setter, rhs);
}
// No writeable field and no setter found in the prefix. Return a
// non-existing setter that will throw an NSM error.
return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs);
}
if (owner().IsLibrary()) {
const Library& library = Library::Cast(owner());
Object& obj = Object::Handle(library.ResolveName(field_name_));
if (obj.IsField()) {
const Field& field = Field::ZoneHandle(Field::Cast(obj).raw());
if (!field.is_final()) {
if (Isolate::Current()->TypeChecksEnabled()) {
rhs = new AssignableNode(field.token_pos(),
rhs,
AbstractType::ZoneHandle(field.type()),
field_name_);
}
return new StoreStaticFieldNode(token_pos(), field, rhs);
}
}
// No field found in library. Look for a setter function.
const String& setter_name = String::Handle(Field::SetterName(field_name_));
obj = library.ResolveName(setter_name);
if (obj.IsFunction()) {
const Function& setter = Function::ZoneHandle(Function::Cast(obj).raw());
ASSERT(setter.is_static() && setter.IsSetterFunction());
return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs);
}
// No writeable field and no setter found in the library. Return a
// non-existing setter that will throw an NSM error.
return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs);
}
const Function& setter =
Function::Handle(cls().LookupSetterFunction(field_name()));
Function::ZoneHandle(cls().LookupSetterFunction(field_name_));
if (!setter.IsNull() && setter.IsStaticFunction()) {
return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs);
return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs);
}
// Could not find a static setter. Look for a field.
// Access to a lazily initialized static field that has not yet been
// initialized is compiled to a static implicit getter.
// A setter may not exist for such a field.
const Field& field = Field::ZoneHandle(cls().LookupStaticField(field_name()));
const Field& field = Field::ZoneHandle(cls().LookupStaticField(field_name_));
if (!field.IsNull()) {
if (field.is_final()) {
// Attempting to assign to a final variable will cause a NoSuchMethodError
// to be thrown. Change static getter to non-existent static setter in
// order to trigger the throw at runtime.
return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs);
return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs);
}
#if defined(DEBUG)
const String& getter_name = String::Handle(Field::GetterName(field_name()));
const String& getter_name = String::Handle(Field::GetterName(field_name_));
const Function& getter =
Function::Handle(cls().LookupStaticFunction(getter_name));
ASSERT(!getter.IsNull() &&
@ -605,7 +687,7 @@ AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
}
// Didn't find a static setter or a static field. Make a call to
// the non-existent setter to trigger a NoSuchMethodError at runtime.
return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs);
return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs);
}

View file

@ -1286,6 +1286,7 @@ class LoadStaticFieldNode : public AstNode {
const Field& field() const { return field_; }
void set_is_deferred(bool value) { is_deferred_reference_ = value; }
bool is_deferred_reference() const { return is_deferred_reference_; }
virtual void VisitChildren(AstNodeVisitor* visitor) const { }
@ -1550,6 +1551,7 @@ class StaticGetterNode : public AstNode {
const String& field_name)
: AstNode(token_pos),
receiver_(receiver),
owner_(Object::ZoneHandle(cls.raw())),
cls_(cls),
field_name_(field_name),
is_deferred_reference_(false) {
@ -1561,6 +1563,17 @@ class StaticGetterNode : public AstNode {
// The receiver is required for a super getter (an instance method that
// is resolved at compile time rather than at runtime).
AstNode* receiver() const { return receiver_; }
// The getter node needs to remmeber how the getter was referenced
// so that it can resolve a corresponding setter if necessary.
// The owner of this getter is either a class, the top-level library scope,
// or a prefix (if the getter has been referenced throug a library prefix).
void set_owner(const Object& value) {
ASSERT(value.IsLibraryPrefix() || value.IsLibrary() || value.IsClass());
owner_ = value.raw();
}
const Object& owner() const { return owner_; }
const Class& cls() const { return cls_; }
const String& field_name() const { return field_name_; }
bool is_super_getter() const { return receiver_ != NULL; }
@ -1577,6 +1590,7 @@ class StaticGetterNode : public AstNode {
private:
AstNode* receiver_;
Object& owner_;
const Class& cls_;
const String& field_name_;
bool is_deferred_reference_;
@ -1587,16 +1601,36 @@ class StaticGetterNode : public AstNode {
class StaticSetterNode : public AstNode {
public:
// Static setter with resolved setter function.
StaticSetterNode(intptr_t token_pos,
AstNode* receiver,
const String& field_name,
const Function& function,
AstNode* value)
: AstNode(token_pos),
receiver_(receiver),
cls_(Class::ZoneHandle(function.Owner())),
field_name_(field_name),
function_(function),
value_(value) {
ASSERT(function_.IsZoneHandle());
ASSERT(function.is_static() || receiver != NULL);
ASSERT(field_name_.IsZoneHandle());
ASSERT(value_ != NULL);
}
// For unresolved setters.
StaticSetterNode(intptr_t token_pos,
AstNode* receiver,
const Class& cls,
const String& field_name,
AstNode* value)
: AstNode(token_pos),
receiver_(receiver),
cls_(cls),
field_name_(field_name),
value_(value) {
: AstNode(token_pos),
receiver_(receiver),
cls_(cls),
field_name_(field_name),
function_(Function::ZoneHandle()),
value_(value) {
ASSERT(cls_.IsZoneHandle());
ASSERT(field_name_.IsZoneHandle());
ASSERT(value_ != NULL);
@ -1607,6 +1641,8 @@ class StaticSetterNode : public AstNode {
AstNode* receiver() const { return receiver_; }
const Class& cls() const { return cls_; }
const String& field_name() const { return field_name_; }
// function() returns null for unresolved setters.
const Function& function() const { return function_; }
AstNode* value() const { return value_; }
virtual void VisitChildren(AstNodeVisitor* visitor) const {
@ -1619,6 +1655,7 @@ class StaticSetterNode : public AstNode {
AstNode* receiver_;
const Class& cls_;
const String& field_name_;
const Function& function_;
AstNode* value_;
DISALLOW_IMPLICIT_CONSTRUCTORS(StaticSetterNode);

View file

@ -499,6 +499,7 @@ void AwaitTransformer::VisitStaticGetterNode(StaticGetterNode* node) {
new_receiver,
node->cls(),
node->field_name());
new_getter->set_owner(node->owner());
LocalVariable* result = AddToPreambleNewTempVar(new_getter);
result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
}
@ -510,12 +511,20 @@ void AwaitTransformer::VisitStaticSetterNode(StaticSetterNode* node) {
new_receiver = Transform(new_receiver);
}
AstNode* new_value = Transform(node->value());
LocalVariable* result = AddToPreambleNewTempVar(
new(Z) StaticSetterNode(node->token_pos(),
new_receiver,
node->cls(),
node->field_name(),
new_value));
StaticSetterNode* new_setter =
node->function().IsNull()
? new(Z) StaticSetterNode(node->token_pos(),
new_receiver,
node->cls(),
node->field_name(),
new_value)
: new(Z) StaticSetterNode(node->token_pos(),
new_receiver,
node->field_name(),
node->function(),
new_value);
LocalVariable* result = AddToPreambleNewTempVar(new_setter);
result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
}

View file

@ -3166,10 +3166,7 @@ void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node,
// resolved at compile time (in the caller instance getter's super class).
// Unlike a static getter, a super getter has a receiver parameter.
const bool is_super_setter = (node->receiver() != NULL);
Function& setter_function =
Function::ZoneHandle(Z, is_super_setter
? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name)
: node->cls().LookupStaticFunction(setter_name));
const Function& setter_function = node->function();
StaticCallInstr* call;
if (setter_function.IsNull()) {
if (is_super_setter) {

View file

@ -9343,6 +9343,7 @@ RawObject* Library::LookupImportedObject(const String& name) const {
String& import_lib_url = String::Handle();
String& first_import_lib_url = String::Handle();
Object& found_obj = Object::Handle();
String& found_obj_name = String::Handle();
for (intptr_t i = 0; i < num_imports(); i++) {
import ^= ImportAt(i);
obj = import.Lookup(name);
@ -9358,13 +9359,28 @@ RawObject* Library::LookupImportedObject(const String& name) const {
// from the Dart library.
first_import_lib_url = import_lib.url();
found_obj = obj.raw();
found_obj_name = obj.DictionaryName();
} else if (import_lib_url.StartsWith(Symbols::DartScheme())) {
// The newly found object is exported from a Dart system
// library. It is hidden by the previously found object.
// We continue to search.
} else {
// We found two different objects with the same name.
return Object::null();
// Note that we need to compare the names again because
// looking up an unmangled name can return a getter or a
// setter. A getter name is the same as the unmangled name,
// but a setter name is different from an unmangled name or a
// getter name.
if (Field::IsGetterName(found_obj_name)) {
found_obj_name = Field::NameFromGetter(found_obj_name);
}
String& second_obj_name = String::Handle(obj.DictionaryName());
if (Field::IsGetterName(second_obj_name)) {
second_obj_name = Field::NameFromGetter(second_obj_name);
}
if (found_obj_name.Equals(second_obj_name)) {
return Object::null();
}
}
}
}
@ -10337,7 +10353,7 @@ RawObject* Namespace::Lookup(const String& name) const {
if (Field::IsGetterName(name)) {
filter_name = &String::Handle(Field::NameFromGetter(name));
} else if (Field::IsSetterName(name)) {
filter_name = &String::Handle(Field::NameFromGetter(name));
filter_name = &String::Handle(Field::NameFromSetter(name));
} else {
if (obj.IsNull() || obj.IsLibraryPrefix()) {
obj = lib.LookupEntry(String::Handle(Field::GetterName(name)), &ignore);

View file

@ -3912,8 +3912,8 @@ void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) {
if (field->has_static && has_initializer) {
class_field.set_value(init_value);
if (!has_simple_literal) {
String& getter_name = String::Handle(Z,
Field::GetterSymbol(*field->name));
String& getter_name =
String::Handle(Z, Field::GetterSymbol(*field->name));
getter = Function::New(getter_name,
RawFunction::kImplicitStaticFinalGetter,
field->has_static,
@ -3934,8 +3934,8 @@ void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) {
// For instance fields, we create implicit getter and setter methods.
if (!field->has_static) {
String& getter_name = String::Handle(Z,
Field::GetterSymbol(*field->name));
String& getter_name =
String::Handle(Z, Field::GetterSymbol(*field->name));
getter = Function::New(getter_name, RawFunction::kImplicitGetter,
field->has_static,
field->has_final,
@ -3953,8 +3953,8 @@ void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) {
members->AddFunction(getter);
if (!field->has_final) {
// Build a setter accessor for non-const fields.
String& setter_name = String::Handle(Z,
Field::SetterSymbol(*field->name));
String& setter_name =
String::Handle(Z, Field::SetterSymbol(*field->name));
setter = Function::New(setter_name, RawFunction::kImplicitSetter,
field->has_static,
field->has_final,
@ -10529,7 +10529,8 @@ AstNode* Parser::ParseCascades(AstNode* expr) {
static AstNode* LiteralIfStaticConst(Zone* zone, AstNode* expr) {
if (expr->IsLoadStaticFieldNode()) {
const Field& field = expr->AsLoadStaticFieldNode()->field();
if (field.is_const()) {
if (field.is_const() &&
!expr->AsLoadStaticFieldNode()->is_deferred_reference()) {
ASSERT(field.value() != Object::sentinel().raw());
ASSERT(field.value() != Object::transition_sentinel().raw());
return new(zone) LiteralNode(expr->token_pos(),
@ -10898,24 +10899,17 @@ AstNode* Parser::GenerateStaticFieldLookup(const Field& field,
}
AstNode* Parser::ParseStaticFieldAccess(const Class& cls,
const String& field_name,
intptr_t ident_pos,
bool consume_cascades) {
TRACE_PARSER("ParseStaticFieldAccess");
// Reference to 'field_name' with explicit class as primary.
AstNode* Parser::GenerateStaticFieldAccess(const Class& cls,
const String& field_name,
intptr_t ident_pos) {
AstNode* access = NULL;
const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(field_name));
Function& func = Function::ZoneHandle(Z);
if (field.IsNull()) {
// No field, check if we have an explicit getter function.
const String& getter_name =
String::ZoneHandle(Z, Field::GetterName(field_name));
const int kNumArguments = 0; // no arguments.
func = Resolver::ResolveStatic(cls,
getter_name,
kNumArguments,
Object::empty_array());
if (func.IsNull()) {
func = cls.LookupGetterFunction(field_name);
if (func.IsNull() || func.IsDynamicFunction()) {
// We might be referring to an implicit closure, check to see if
// there is a function of the same name.
func = cls.LookupStaticFunction(field_name);
@ -11056,12 +11050,14 @@ AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) {
} else {
// Field access.
Class& cls = Class::Handle(Z);
bool is_deferred = false;
if (left->IsPrimaryNode()) {
PrimaryNode* primary_node = left->AsPrimaryNode();
if (primary_node->primary().IsClass()) {
// If the primary node referred to a class we are loading a
// qualified static field.
cls ^= primary_node->primary().raw();
is_deferred = primary_node->is_deferred_reference();
}
}
if (cls.IsNull()) {
@ -11069,8 +11065,13 @@ AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) {
selector = CallGetter(ident_pos, left, *ident);
} else {
// Static field access.
selector =
ParseStaticFieldAccess(cls, *ident, ident_pos, !is_cascade);
selector = GenerateStaticFieldAccess(cls, *ident, ident_pos);
ASSERT(selector != NULL);
if (selector->IsLoadStaticFieldNode()) {
selector->AsLoadStaticFieldNode()->set_is_deferred(is_deferred);
} else if (selector->IsStaticGetterNode()) {
selector->AsStaticGetterNode()->set_is_deferred(is_deferred);
}
}
}
} else if (CurrentToken() == Token::kLBRACK) {
@ -11466,8 +11467,8 @@ RawInstance* Parser::TryCanonicalize(const Instance& instance,
// If the field is already initialized, return no ast (NULL).
// Otherwise, if the field is constant, initialize the field and return no ast.
// If the field is not initialized and not const, return the ast for the getter.
AstNode* Parser::RunStaticFieldInitializer(const Field& field,
intptr_t field_ref_pos) {
StaticGetterNode* Parser::RunStaticFieldInitializer(const Field& field,
intptr_t field_ref_pos) {
ASSERT(field.is_static());
const Class& field_owner = Class::ZoneHandle(Z, field.owner());
const String& field_name = String::ZoneHandle(Z, field.name());
@ -11752,16 +11753,22 @@ AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos,
} else if (obj.IsField()) {
const Field& field = Field::Cast(obj);
ASSERT(field.is_static());
return GenerateStaticFieldLookup(field, ident_pos);
AstNode* get_field = GenerateStaticFieldLookup(field, ident_pos);
if (get_field->IsStaticGetterNode()) {
get_field->AsStaticGetterNode()->set_owner(library_);
}
return get_field;
} else if (obj.IsFunction()) {
const Function& func = Function::Cast(obj);
ASSERT(func.is_static());
if (func.IsGetterFunction() || func.IsSetterFunction()) {
return new(Z) StaticGetterNode(ident_pos,
/* receiver */ NULL,
Class::ZoneHandle(Z, func.Owner()),
ident);
StaticGetterNode* getter =
new(Z) StaticGetterNode(ident_pos,
/* receiver */ NULL,
Class::ZoneHandle(Z, func.Owner()),
ident);
getter->set_owner(library_);
return getter;
} else {
return new(Z) PrimaryNode(ident_pos, Function::ZoneHandle(Z, func.raw()));
}
@ -11796,7 +11803,7 @@ AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos,
// Private names are not exported by libraries. The name mangling
// of private names with a library-specific suffix usually ensures
// that _x in library A is not found when looked up from library B.
// In the pathological case where a library includes itself with
// In the pathological case where a library imports itself with
// a prefix, the name mangling would not help in hiding the private
// name, so we need to explicitly reject private names here.
return NULL;
@ -11833,6 +11840,7 @@ AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos,
get_field->AsLoadStaticFieldNode()->set_is_deferred(is_deferred);
} else if (get_field->IsStaticGetterNode()) {
get_field->AsStaticGetterNode()->set_is_deferred(is_deferred);
get_field->AsStaticGetterNode()->set_owner(prefix);
}
return get_field;
} else if (obj.IsFunction()) {
@ -11840,11 +11848,12 @@ AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos,
ASSERT(func.is_static());
if (func.IsGetterFunction() || func.IsSetterFunction()) {
StaticGetterNode* getter = new(Z) StaticGetterNode(
ident_pos,
/* receiver */ NULL,
Class::ZoneHandle(Z, func.Owner()),
ident);
ident_pos,
/* receiver */ NULL,
Class::ZoneHandle(Z, func.Owner()),
ident);
getter->set_is_deferred(is_deferred);
getter->set_owner(prefix);
return getter;
} else {
PrimaryNode* primary = new(Z) PrimaryNode(

View file

@ -381,8 +381,8 @@ class Parser : public ValueObject {
void CheckRecursiveInvocation();
const Instance& EvaluateConstExpr(intptr_t expr_pos, AstNode* expr);
AstNode* RunStaticFieldInitializer(const Field& field,
intptr_t field_ref_pos);
StaticGetterNode* RunStaticFieldInitializer(const Field& field,
intptr_t field_ref_pos);
RawObject* EvaluateConstConstructorCall(const Class& type_class,
const TypeArguments& type_arguments,
const Function& constructor,
@ -711,10 +711,9 @@ class Parser : public ValueObject {
AstNode* ParseClosureCall(AstNode* closure);
AstNode* GenerateStaticFieldLookup(const Field& field,
intptr_t ident_pos);
AstNode* ParseStaticFieldAccess(const Class& cls,
const String& field_name,
intptr_t ident_pos,
bool consume_cascades);
AstNode* GenerateStaticFieldAccess(const Class& cls,
const String& field_name,
intptr_t ident_pos);
LocalVariable* LookupLocalScope(const String& ident);
void CheckInstanceFieldAccess(intptr_t field_pos, const String& field_name);

View file

@ -6,3 +6,5 @@ library GetterSetterInLib;
get foo => 42;
set foo(a) {}
get bar => 77;

View file

@ -0,0 +1,7 @@
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library GetterSetterInLib2;
set bar(a) { }

View file

@ -0,0 +1,11 @@
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library GetterSetterInLib3;
var _f = 33;
set bar(a) { _f = a; }
get bar => _f;

View file

@ -5,9 +5,19 @@
library GetterSetterInLibTest;
import "package:expect/expect.dart";
import 'getter_setter_in_lib.dart';
import 'getter_setter_in_lib2.dart';
import 'getter_setter_in_lib3.dart' as L3;
main() {
Expect.equals(42, foo);
foo = 43;
Expect.equals(42, foo);
Expect.equals(77, bar);
bar = 43;
Expect.equals(77, bar);
Expect.equals(L3.bar, 33);
L3.bar = 44;
Expect.equals(L3.bar, 44);
}

View file

@ -40,6 +40,7 @@ deferred_inlined_test: Fail # Issue 17523
deferred_optimized_test: Fail # Issue 17523
regress_22443_test: Fail # Issue 17523
enum_mirror_test: Skip # Issue 11511.
getter_setter_in_lib_test: Fail # Issue 23288
override_inheritance_mixed_test/08: Fail # Issue 18124
override_inheritance_mixed_test/09: Fail # Issue 18124

View file

@ -13,6 +13,7 @@ await_test: CompileTimeError # Issue 22052
async_await_test/02: CompileTimeError # Issue 22052
regress_17382_test: Skip # don't care about the static warning.
regress_23038_test/01: Skip # Issue 23038
getter_setter_in_lib_test: Fail # issue 23286
issue13179_test: CompileTimeError # Issue 13179

View file

@ -14,6 +14,7 @@ enum_syntax_test/05: Fail # 21649
enum_syntax_test/06: Fail # 21649
regress_17382_test: Skip # don't care about the static warning.
getter_setter_in_lib_test: Fail # issue 23286
# Test issue 12694 (was analyzer issue), (1) when "abstract" is import prefix using it as type is warning; (2) currently analyzer resolves prefix as field (don't ask)
built_in_identifier_prefix_test: CompileTimeError # Issue 12694

View file

@ -6,6 +6,7 @@
sync_generator2_test/07: MissingCompileTimeError # Issue 22324
sync_generator2_test/08: MissingCompileTimeError # Issue 22324
sync_generator2_test/10: MissingCompileTimeError # Issue 22324
getter_setter_in_lib_test: Fail # Issue 23288
async_star_test/02: RuntimeError # 22853
async_star_test/05: RuntimeError, Timeout