Skip to content

Commit

Permalink
[[FIX]] Correctly interpret class method names
Browse files Browse the repository at this point in the history
  • Loading branch information
jugglinmike authored and rwaldron committed Apr 9, 2019
1 parent f670aeb commit 82b49c4
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 30 deletions.
63 changes: 33 additions & 30 deletions src/jshint.js
Expand Up @@ -2843,6 +2843,24 @@ var JSHINT = (function() {
}

token = state.tokens.next;

if ((token.value === "set" || token.value === "get") && !checkPunctuator(peek(), "(")) {
if (inGenerator) {
error("E024", token, token.value);
}
accessorType = token.value;
advance();
token = state.tokens.next;

if (!isStatic && token.value === "constructor") {
error("E049", token, "class " + accessorType + "ter method", token.value);
} else if (isStatic && token.value === "prototype") {
error("E049", token, "static class " + accessorType + "ter method", token.value);
}
} else {
accessorType = null;
}

switch (token.value) {
case ";":
warning("W032", token);
Expand All @@ -2857,37 +2875,14 @@ var JSHINT = (function() {
} else {
if (inGenerator || context & prodParams.preAsync) {
error("E024", token, token.value);
}
if (hasConstructor) {
} else if (hasConstructor) {
error("E024", token, token.value);
} else {
hasConstructor = !accessorType && !isStatic;
}
advance();
doMethod(classToken, context, state.nameStack.infer());
hasConstructor = true;
}
break;
case "set":
case "get":
if (inGenerator) {
error("E024", token, token.value);
}
accessorType = token.value;
advance();

if (state.tokens.next.value === "[") {
name = computedPropertyName(context);
doMethod(classToken, context, name, false);
} else {
name = propertyName(context);
if (!isStatic && name === "constructor") {
error("E049", state.tokens.curr, "class " + accessorType + "ter method", name);
} else if (isStatic && name === "prototype") {
error("E049", state.tokens.curr, "static class " + accessorType + "ter method", name);
}
saveAccessor(accessorType, props, name, state.tokens.curr, true, isStatic);
doMethod(classToken, context, state.nameStack.infer(), false);
}

break;
case "[":
name = computedPropertyName(context);
Expand All @@ -2896,15 +2891,23 @@ var JSHINT = (function() {
break;
default:
name = propertyName(context);
if (!name) {
if (name === undefined) {
error("E024", token, token.value);
advance();
break;
}
if (isStatic && name === "prototype") {
error("E049", token, "static class method", name);

if (accessorType) {
saveAccessor(accessorType, props, name, token, true, isStatic);
name = state.nameStack.infer();
} else {
if (isStatic && name === "prototype") {
error("E049", token, "static class method", name);
}

saveProperty(props, name, token, true, isStatic);
}
saveProperty(props, name, token, true, isStatic);

doMethod(classToken, context, name, inGenerator);
break;
}
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/parser.js
Expand Up @@ -6256,6 +6256,13 @@ exports["object ComputedPropertyName"] = function (test) {
.addError(19, 17, "Setter is defined without getter.")
.test(code, { esnext: true });

TestRun(test, "regression test for gh-3381")
.test([
"void {",
" set() {}",
"};"
], {esversion: 6});

TestRun(test)
.addError(6, 1, "'computed property names' is only available in ES6 (use 'esversion: 6').")
.addError(7, 8, "'computed property names' is only available in ES6 (use 'esversion: 6').")
Expand Down Expand Up @@ -6720,6 +6727,13 @@ exports["class and method naming"] = function (test) {
"};"
], {esversion: 6});

TestRun(test, "regression test for gh-3381")
.test([
"void class {",
" set() {}",
"};"
], {esversion: 6});

TestRun(test, "hazardous method names (see gh-3358)")
.addError(3, 17, "'hasOwnProperty' is a really bad name.")
.test([
Expand Down

0 comments on commit 82b49c4

Please sign in to comment.