fd57843900
Update VM to latest spec. Referencing a name that is imported from more than one library is no longer a compile-time error. If one of the sources of an ambiguous reference is a dart library, the dart library declaration is automatically hidden. Also fixes a bug where looking up a getter name in a library found the getter even though the name is filtered out in the 'hide' combinator. Long-term we should fix the need for repeatedly convert between the mangled getter and setter names and the untangled name. Fixes 12915, 12913, 12724. R=regis@google.com Review URL: https://codereview.chromium.org//23484020 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@27312 260f80e4-7a28-3924-810f-c04153c831b5
170 lines
5.7 KiB
C++
170 lines
5.7 KiB
C++
// Copyright (c) 2011, 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.
|
|
|
|
|
|
#include "vm/ast_printer.h"
|
|
#include "vm/class_finalizer.h"
|
|
#include "vm/longjump.h"
|
|
#include "vm/object.h"
|
|
#include "vm/parser.h"
|
|
#include "vm/symbols.h"
|
|
#include "vm/unit_test.h"
|
|
|
|
namespace dart {
|
|
|
|
|
|
void DumpFunction(const Library& lib, const char* cname, const char* fname) {
|
|
const String& classname = String::Handle(Symbols::New(cname));
|
|
Class& cls = Class::Handle(lib.LookupClass(classname));
|
|
EXPECT(!cls.IsNull());
|
|
|
|
String& funcname = String::Handle(String::New(fname));
|
|
Function& function = Function::ZoneHandle(cls.LookupStaticFunction(funcname));
|
|
EXPECT(!function.IsNull());
|
|
|
|
bool retval;
|
|
Isolate* isolate = Isolate::Current();
|
|
EXPECT(isolate != NULL);
|
|
LongJump* base = isolate->long_jump_base();
|
|
LongJump jump;
|
|
isolate->set_long_jump_base(&jump);
|
|
if (setjmp(*jump.Set()) == 0) {
|
|
ParsedFunction* parsed_function = new ParsedFunction(function);
|
|
Parser::ParseFunction(parsed_function);
|
|
EXPECT(parsed_function->node_sequence() != NULL);
|
|
printf("Class %s function %s:\n", cname, fname);
|
|
AstPrinter::PrintFunctionNodes(*parsed_function);
|
|
retval = true;
|
|
} else {
|
|
retval = false;
|
|
}
|
|
EXPECT(retval);
|
|
isolate->set_long_jump_base(base);
|
|
}
|
|
|
|
|
|
void CheckField(const Library& lib,
|
|
const char* class_name,
|
|
const char* field_name,
|
|
bool expect_static,
|
|
bool is_final) {
|
|
const String& classname = String::Handle(Symbols::New(class_name));
|
|
Class& cls = Class::Handle(lib.LookupClass(classname));
|
|
EXPECT(!cls.IsNull());
|
|
|
|
String& fieldname = String::Handle(String::New(field_name));
|
|
String& functionname = String::Handle();
|
|
Function& function = Function::Handle();
|
|
Field& field = Field::Handle();
|
|
if (expect_static) {
|
|
field ^= cls.LookupStaticField(fieldname);
|
|
functionname ^= Field::GetterName(fieldname);
|
|
function ^= cls.LookupStaticFunction(functionname);
|
|
EXPECT(function.IsNull());
|
|
functionname ^= Field::SetterName(fieldname);
|
|
function ^= cls.LookupStaticFunction(functionname);
|
|
EXPECT(function.IsNull());
|
|
} else {
|
|
field ^= cls.LookupInstanceField(fieldname);
|
|
functionname ^= Field::GetterName(fieldname);
|
|
function ^= cls.LookupDynamicFunction(functionname);
|
|
EXPECT(!function.IsNull());
|
|
functionname ^= Field::SetterName(fieldname);
|
|
function ^= cls.LookupDynamicFunction(functionname);
|
|
EXPECT(is_final ? function.IsNull() : !function.IsNull());
|
|
}
|
|
EXPECT(!field.IsNull());
|
|
|
|
EXPECT_EQ(field.is_static(), expect_static);
|
|
}
|
|
|
|
|
|
void CheckFunction(const Library& lib,
|
|
const char* class_name,
|
|
const char* function_name,
|
|
bool expect_static) {
|
|
const String& classname = String::Handle(Symbols::New(class_name));
|
|
Class& cls = Class::Handle(lib.LookupClass(classname));
|
|
EXPECT(!cls.IsNull());
|
|
|
|
String& functionname = String::Handle(String::New(function_name));
|
|
Function& function = Function::Handle();
|
|
if (expect_static) {
|
|
function ^= cls.LookupStaticFunction(functionname);
|
|
} else {
|
|
function ^= cls.LookupDynamicFunction(functionname);
|
|
}
|
|
EXPECT(!function.IsNull());
|
|
}
|
|
|
|
|
|
TEST_CASE(ParseClassDefinition) {
|
|
const char* script_chars =
|
|
"class C { } \n"
|
|
"class A { \n"
|
|
" var f0; \n"
|
|
" int f1; \n"
|
|
" final f2; \n"
|
|
" final int f3, f4; \n"
|
|
" static String s1, s2; \n"
|
|
" static const int s3 = 8675309; \n"
|
|
" static bar(i, [var d = 5]) { return 77; } \n"
|
|
" static foo() native \"native_function_name\"; \n"
|
|
"} \n";
|
|
|
|
String& url = String::Handle(String::New("dart-test:Parser_TopLevel"));
|
|
String& source = String::Handle(String::New(script_chars));
|
|
Script& script = Script::Handle(Script::New(url,
|
|
source,
|
|
RawScript::kScriptTag));
|
|
Library& lib = Library::ZoneHandle(Library::CoreLibrary());
|
|
|
|
script.Tokenize(String::Handle(String::New("")));
|
|
|
|
Parser::ParseCompilationUnit(lib, script);
|
|
EXPECT(ClassFinalizer::FinalizePendingClasses());
|
|
CheckField(lib, "A", "f1", false, false);
|
|
CheckField(lib, "A", "f2", false, true);
|
|
CheckField(lib, "A", "f3", false, true);
|
|
CheckField(lib, "A", "f4", false, true);
|
|
CheckField(lib, "A", "s1", true, false);
|
|
CheckField(lib, "A", "s2", true, false);
|
|
CheckField(lib, "A", "s3", true, true);
|
|
CheckFunction(lib, "A", "bar", true);
|
|
CheckFunction(lib, "A", "foo", true);
|
|
}
|
|
|
|
|
|
TEST_CASE(Parser_TopLevel) {
|
|
const char* script_chars =
|
|
"class A extends B { \n"
|
|
" static bar(var i, [var d = 5]) { return 77; } \n"
|
|
" static foo() { return 42; } \n"
|
|
" static baz(var i) { var q = 5; return i + q; } \n"
|
|
"} \n"
|
|
" \n"
|
|
"class B { \n"
|
|
" static bam(k) { return A.foo(); } \n"
|
|
"} \n";
|
|
|
|
String& url = String::Handle(String::New("dart-test:Parser_TopLevel"));
|
|
String& source = String::Handle(String::New(script_chars));
|
|
Script& script = Script::Handle(Script::New(url,
|
|
source,
|
|
RawScript::kScriptTag));
|
|
Library& lib = Library::ZoneHandle(Library::CoreLibrary());
|
|
|
|
script.Tokenize(String::Handle(String::New("")));
|
|
|
|
Parser::ParseCompilationUnit(lib, script);
|
|
EXPECT(ClassFinalizer::FinalizePendingClasses());
|
|
|
|
DumpFunction(lib, "A", "foo");
|
|
DumpFunction(lib, "A", "bar");
|
|
DumpFunction(lib, "A", "baz");
|
|
DumpFunction(lib, "B", "bam");
|
|
}
|
|
|
|
} // namespace dart
|