Version 1.0.0.9
svn merge -c 30385 https://dart.googlecode.com/svn/branches/bleeding_edge/dart .
svn merge -c 30491 https://dart.googlecode.com/svn/branches/bleeding_edge/dart .
R=ricow@google.com
Review URL: https://codereview.chromium.org//75503007
git-svn-id: http://dart.googlecode.com/svn/trunk@30494 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 4fc43e0..1ea5b70 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -232,6 +232,7 @@
token_kind_(Token::kILLEGAL),
current_block_(NULL),
is_top_level_(false),
+ parsing_metadata_(false),
current_member_(NULL),
allow_function_literals_(true),
parsed_function_(NULL),
@@ -258,6 +259,7 @@
token_kind_(Token::kILLEGAL),
current_block_(NULL),
is_top_level_(false),
+ parsing_metadata_(false),
current_member_(NULL),
allow_function_literals_(true),
parsed_function_(parsed_function),
@@ -847,6 +849,7 @@
const Library& lib = Library::Handle(cls.library());
Parser parser(script, lib, token_pos);
parser.set_current_class(cls);
+ parser.set_parsing_metadata(true);
return parser.EvaluateMetadata();
} else {
Error& error = Error::Handle();
@@ -8230,7 +8233,13 @@
// NoSuchMethodError to be thrown.
// In an instance method, we convert this into a getter call
// for a field (which may be defined in a subclass.)
+ // In metadata, an unresolved identifier cannot be a compile-time constant.
String& name = String::CheckedZoneHandle(primary->primary().raw());
+ if (parsing_metadata_) {
+ ErrorMsg(primary->token_pos(),
+ "unresolved identifier '%s' is not a compile-time constant",
+ name.ToCString());
+ }
if (current_function().is_static() ||
current_function().IsInFactoryScope()) {
return new StaticGetterNode(primary->token_pos(),
@@ -8258,6 +8267,11 @@
closure = CreateImplicitClosureNode(func, primary->token_pos(), NULL);
} else {
// Instance function access.
+ if (parsing_metadata_) {
+ ErrorMsg(primary->token_pos(),
+ "cannot access instance method '%s' from metadata",
+ funcname.ToCString());
+ }
if (current_function().is_static() ||
current_function().IsInFactoryScope()) {
ErrorMsg(primary->token_pos(),
@@ -8640,6 +8654,11 @@
const String& field_name) {
// Fields are not accessible from a static function, except from a
// constructor, which is considered as non-static by the compiler.
+ if (parsing_metadata_) {
+ ErrorMsg(field_pos,
+ "cannot access instance field '%s' from metadata",
+ field_name.ToCString());
+ }
if (current_function().is_static()) {
ErrorMsg(field_pos,
"cannot access instance field '%s' from a static function",
@@ -10281,6 +10300,9 @@
} else if (CurrentToken() == Token::kHASH) {
primary = ParseSymbolLiteral();
} else if (CurrentToken() == Token::kSUPER) {
+ if (parsing_metadata_) {
+ ErrorMsg("cannot access superclass from metadata");
+ }
if (current_function().is_static()) {
ErrorMsg("cannot access superclass from static method");
}
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 7b82f6b..7be1bc0 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -655,6 +655,11 @@
// global variables.
bool is_top_level_;
+ // True when evaluating metadata. Used to make decisions otherwise based on
+ // the current_function().
+ void set_parsing_metadata(bool value) { parsing_metadata_ = value; }
+ bool parsing_metadata_;
+
// The member currently being parsed during "top level" parsing.
MemberDesc* current_member_;
diff --git a/tests/lib/mirrors/metadata_allowed_values_test.dart b/tests/lib/mirrors/metadata_allowed_values_test.dart
index 77e7374..d410a63 100644
--- a/tests/lib/mirrors/metadata_allowed_values_test.dart
+++ b/tests/lib/mirrors/metadata_allowed_values_test.dart
@@ -2,7 +2,7 @@
// 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 test.metadata_with_type_literal;
+library test.metadata_allowed_values;
import 'dart:mirrors';
import 'package:expect/expect.dart';
diff --git a/tests/lib/mirrors/metadata_constructor_arguments_test.dart b/tests/lib/mirrors/metadata_constructor_arguments_test.dart
new file mode 100644
index 0000000..938270e
--- /dev/null
+++ b/tests/lib/mirrors/metadata_constructor_arguments_test.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for Issue 13817.
+
+library test.metadata_constructor_arguments;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class Tag {
+ final name;
+ const Tag({named}) : this.name = named;
+}
+
+@Tag(named: undefined) /// 01: compile-time error
+class A {}
+
+@Tag(named: 'valid')
+class B {}
+
+@Tag(named: C.STATIC_FIELD)
+class C {
+ static const STATIC_FIELD = 3;
+}
+
+@Tag(named: D.instanceMethod()) /// 02: compile-time error
+class D {
+ instanceMethod() {}
+}
+
+@Tag(named: instanceField) /// 03: compile-time error
+class E {
+ var instanceField;
+}
+
+@Tag(named: F.nonConstStaticField) /// 04: compile-time error
+class F {
+ static var nonConstStaticField = 6;
+}
+
+@Tag(named: instanceMethod) /// 05: compile-time error
+class G {
+ instanceMethod() {}
+}
+
+@Tag(named: this) /// 06: compile-time error
+class H {
+ instanceMethod() {}
+}
+
+@Tag(named: super) /// 07: compile-time error
+class I {
+ instanceMethod() {}
+}
+
+checkMetadata(DeclarationMirror mirror, List expectedMetadata) {
+ Expect.listEquals(expectedMetadata.map(reflect).toList(), mirror.metadata);
+}
+
+main() {
+ reflectClass(A).metadata;
+ checkMetadata(reflectClass(B), [const Tag(named: 'valid')]);
+ checkMetadata(reflectClass(C), [const Tag(named: C.STATIC_FIELD)]);
+ reflectClass(D).metadata;
+ reflectClass(E).metadata;
+ reflectClass(F).metadata;
+ reflectClass(G).metadata;
+ reflectClass(H).metadata;
+ reflectClass(I).metadata;
+}
diff --git a/tools/VERSION b/tools/VERSION
index 8248219..52b6cb0 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
MAJOR 1
MINOR 0
BUILD 0
-PATCH 8
+PATCH 9