regexp: change Expr() to String(); add HasOperator method to Regexp.
It reports whether a regular expression has operators
as opposed to matching literal text.

R=rsc, gri
CC=golang-dev
https://golang.org/cl/3731041
diff --git a/src/pkg/regexp/all_test.go b/src/pkg/regexp/all_test.go
index 5b614de..8f115aa 100644
--- a/src/pkg/regexp/all_test.go
+++ b/src/pkg/regexp/all_test.go
@@ -229,18 +229,21 @@
 	}
 }
 
-type QuoteMetaTest struct {
-	pattern, output string
+type MetaTest struct {
+	pattern, output, literal string
+	isLiteral                bool
 }
 
-var quoteMetaTests = []QuoteMetaTest{
-	{``, ``},
-	{`foo`, `foo`},
-	{`!@#$%^&*()_+-=[{]}\|,<.>/?~`, `!@#\$%\^&\*\(\)_\+-=\[{\]}\\\|,<\.>/\?~`},
+var metaTests = []MetaTest{
+	{``, ``, ``, true},
+	{`foo`, `foo`, `foo`, true},
+	{`foo\.\$`, `foo\\\.\\\$`, `foo.$`, true}, // has meta but no operator
+	{`foo.\$`, `foo\.\\\$`, `foo`, false},     // has escaped operators and real operators
+	{`!@#$%^&*()_+-=[{]}\|,<.>/?~`, `!@#\$%\^&\*\(\)_\+-=\[{\]}\\\|,<\.>/\?~`, `!@#`, false},
 }
 
 func TestQuoteMeta(t *testing.T) {
-	for _, tc := range quoteMetaTests {
+	for _, tc := range metaTests {
 		// Verify that QuoteMeta returns the expected string.
 		quoted := QuoteMeta(tc.pattern)
 		if quoted != tc.output {
@@ -269,14 +272,16 @@
 	}
 }
 
-func TestHasMeta(t *testing.T) {
-	for _, tc := range quoteMetaTests {
-		// HasMeta should be false if QuoteMeta returns the original string;
-		// true otherwise.
-		quoted := QuoteMeta(tc.pattern)
-		if HasMeta(tc.pattern) != (quoted != tc.pattern) {
-			t.Errorf("HasMeta(`%s`) = %t; want %t",
-				tc.pattern, HasMeta(tc.pattern), quoted != tc.pattern)
+func TestLiteralPrefix(t *testing.T) {
+	for _, tc := range metaTests {
+		// Literal method needs to scan the pattern.
+		re := MustCompile(tc.pattern)
+		str, complete := re.LiteralPrefix()
+		if complete != tc.isLiteral {
+			t.Errorf("LiteralPrefix(`%s`) = %t; want %t", tc.pattern, complete, tc.isLiteral)
+		}
+		if str != tc.literal {
+			t.Errorf("LiteralPrefix(`%s`) = `%s`; want `%s`", tc.pattern, str, tc.literal)
 		}
 	}
 }