summaryrefslogtreecommitdiffstats
path: root/js/src/util/Identifier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/util/Identifier.cpp')
-rw-r--r--js/src/util/Identifier.cpp155
1 files changed, 155 insertions, 0 deletions
diff --git a/js/src/util/Identifier.cpp b/js/src/util/Identifier.cpp
new file mode 100644
index 0000000000..0de987180a
--- /dev/null
+++ b/js/src/util/Identifier.cpp
@@ -0,0 +1,155 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "util/Identifier.h"
+
+#include "mozilla/Assertions.h" // MOZ_ASSERT
+
+#include <stddef.h> // size_t
+
+#include "js/GCAPI.h" // JS::AutoCheckCannotGC
+#include "js/TypeDecls.h" // JS::Latin1Char
+#include "util/Unicode.h" // unicode::{IsIdentifierStart, IsIdentifierPart, IsIdentifierStartASCII, IsIdentifierPartASCII, IsLeadSurrogate, IsTrailSurrogate, UTF16Decode}
+#include "vm/StringType.h" // JSLinearString
+
+using namespace js;
+
+bool js::IsIdentifier(JSLinearString* str) {
+ JS::AutoCheckCannotGC nogc;
+ MOZ_ASSERT(str);
+ if (str->hasLatin1Chars()) {
+ return IsIdentifier(str->latin1Chars(nogc), str->length());
+ }
+ return IsIdentifier(str->twoByteChars(nogc), str->length());
+}
+
+bool js::IsIdentifierNameOrPrivateName(JSLinearString* str) {
+ JS::AutoCheckCannotGC nogc;
+ MOZ_ASSERT(str);
+ if (str->hasLatin1Chars()) {
+ return IsIdentifierNameOrPrivateName(str->latin1Chars(nogc), str->length());
+ }
+ return IsIdentifierNameOrPrivateName(str->twoByteChars(nogc), str->length());
+}
+
+bool js::IsIdentifier(const JS::Latin1Char* chars, size_t length) {
+ if (length == 0) {
+ return false;
+ }
+
+ if (!unicode::IsIdentifierStart(char16_t(*chars))) {
+ return false;
+ }
+
+ const JS::Latin1Char* end = chars + length;
+ while (++chars != end) {
+ if (!unicode::IsIdentifierPart(char16_t(*chars))) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool js::IsIdentifierASCII(char c) {
+ return unicode::IsIdentifierStartASCII(c);
+}
+
+bool js::IsIdentifierASCII(char c1, char c2) {
+ return unicode::IsIdentifierStartASCII(c1) &&
+ unicode::IsIdentifierPartASCII(c2);
+}
+
+bool js::IsIdentifierNameOrPrivateName(const JS::Latin1Char* chars,
+ size_t length) {
+ if (length == 0) {
+ return false;
+ }
+
+ // Skip over any private name marker.
+ if (*chars == '#') {
+ ++chars;
+ --length;
+ }
+
+ return IsIdentifier(chars, length);
+}
+
+static char32_t GetSingleCodePoint(const char16_t** p, const char16_t* end) {
+ using namespace js;
+
+ if (MOZ_UNLIKELY(unicode::IsLeadSurrogate(**p)) && *p + 1 < end) {
+ char16_t lead = **p;
+ char16_t maybeTrail = *(*p + 1);
+ if (unicode::IsTrailSurrogate(maybeTrail)) {
+ *p += 2;
+ return unicode::UTF16Decode(lead, maybeTrail);
+ }
+ }
+
+ char32_t codePoint = **p;
+ (*p)++;
+ return codePoint;
+}
+
+bool js::IsIdentifier(const char16_t* chars, size_t length) {
+ if (length == 0) {
+ return false;
+ }
+
+ const char16_t* p = chars;
+ const char16_t* end = chars + length;
+ char32_t codePoint;
+
+ codePoint = GetSingleCodePoint(&p, end);
+ if (!unicode::IsIdentifierStart(codePoint)) {
+ return false;
+ }
+
+ while (p < end) {
+ codePoint = GetSingleCodePoint(&p, end);
+ if (!unicode::IsIdentifierPart(codePoint)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool js::IsIdentifierNameOrPrivateName(const char16_t* chars, size_t length) {
+ if (length == 0) {
+ return false;
+ }
+
+ const char16_t* p = chars;
+ const char16_t* end = chars + length;
+ char32_t codePoint;
+
+ codePoint = GetSingleCodePoint(&p, end);
+
+ // Skip over any private name marker.
+ if (codePoint == '#') {
+ // The identifier part of a private name mustn't be empty.
+ if (length == 1) {
+ return false;
+ }
+
+ codePoint = GetSingleCodePoint(&p, end);
+ }
+
+ if (!unicode::IsIdentifierStart(codePoint)) {
+ return false;
+ }
+
+ while (p < end) {
+ codePoint = GetSingleCodePoint(&p, end);
+ if (!unicode::IsIdentifierPart(codePoint)) {
+ return false;
+ }
+ }
+
+ return true;
+}