mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-03 05:44:10 -08:00
Weaken rules for names of JSProperty methods
First, accept first character if it's a non-letter character. Second, don't validate name of method when JSProperty specifies name of the JS property explicitly. See #277
This commit is contained in:
parent
c0ed3d54d7
commit
3791b806b9
|
@ -333,13 +333,12 @@ class JSClassProcessor {
|
||||||
private boolean processJSBodyInvocation(MethodReader method, CallLocation callLocation, InvokeInstruction invoke,
|
private boolean processJSBodyInvocation(MethodReader method, CallLocation callLocation, InvokeInstruction invoke,
|
||||||
MethodHolder methodToProcess) {
|
MethodHolder methodToProcess) {
|
||||||
boolean[] byRefParams = new boolean[method.parameterCount()];
|
boolean[] byRefParams = new boolean[method.parameterCount()];
|
||||||
boolean valid = validateSignature(method, callLocation, byRefParams);
|
validateSignature(method, callLocation, byRefParams);
|
||||||
if (invoke.getInstance() != null) {
|
if (invoke.getInstance() != null) {
|
||||||
if (!typeHelper.isSupportedType(ValueType.object(method.getOwnerName()))) {
|
if (!typeHelper.isSupportedType(ValueType.object(method.getOwnerName()))) {
|
||||||
diagnostics.error(callLocation, "Method {{m0}} is not a proper native JavaScript method "
|
diagnostics.error(callLocation, "Method {{m0}} is not a proper native JavaScript method "
|
||||||
+ "declaration. It is non-static and declared on a non-overlay class {{c1}}",
|
+ "declaration. It is non-static and declared on a non-overlay class {{c1}}",
|
||||||
invoke.getMethod(), method.getOwnerName());
|
invoke.getMethod(), method.getOwnerName());
|
||||||
valid = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,8 +350,6 @@ class JSClassProcessor {
|
||||||
|
|
||||||
Variable result = invoke.getReceiver() != null ? program.createVariable() : null;
|
Variable result = invoke.getReceiver() != null ? program.createVariable() : null;
|
||||||
InvokeInstruction newInvoke = new InvokeInstruction();
|
InvokeInstruction newInvoke = new InvokeInstruction();
|
||||||
ValueType[] signature = new ValueType[method.parameterCount() + 3];
|
|
||||||
Arrays.fill(signature, ValueType.object(JSObject.class.getName()));
|
|
||||||
newInvoke.setMethod(delegate);
|
newInvoke.setMethod(delegate);
|
||||||
newInvoke.setType(InvocationType.SPECIAL);
|
newInvoke.setType(InvocationType.SPECIAL);
|
||||||
newInvoke.setReceiver(result);
|
newInvoke.setReceiver(result);
|
||||||
|
@ -381,12 +378,9 @@ class JSClassProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean processProperty(MethodReader method, CallLocation callLocation, InvokeInstruction invoke) {
|
private boolean processProperty(MethodReader method, CallLocation callLocation, InvokeInstruction invoke) {
|
||||||
if (isProperGetter(method.getDescriptor())) {
|
if (isProperGetter(method)) {
|
||||||
String propertyName;
|
String propertyName = extractSuggestedPropertyName(method);
|
||||||
AnnotationReader annot = method.getAnnotations().get(JSProperty.class.getName());
|
if (propertyName == null) {
|
||||||
if (annot.getValue("value") != null) {
|
|
||||||
propertyName = annot.getValue("value").getString();
|
|
||||||
} else {
|
|
||||||
propertyName = method.getName().charAt(0) == 'i' ? cutPrefix(method.getName(), 2)
|
propertyName = method.getName().charAt(0) == 'i' ? cutPrefix(method.getName(), 2)
|
||||||
: cutPrefix(method.getName(), 3);
|
: cutPrefix(method.getName(), 3);
|
||||||
}
|
}
|
||||||
|
@ -398,12 +392,9 @@ class JSClassProcessor {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (isProperSetter(method.getDescriptor())) {
|
if (isProperSetter(method)) {
|
||||||
String propertyName;
|
String propertyName = extractSuggestedPropertyName(method);
|
||||||
AnnotationReader annot = method.getAnnotations().get(JSProperty.class.getName());
|
if (propertyName == null) {
|
||||||
if (annot.getValue("value") != null) {
|
|
||||||
propertyName = annot.getValue("value").getString();
|
|
||||||
} else {
|
|
||||||
propertyName = cutPrefix(method.getName(), 3);
|
propertyName = cutPrefix(method.getName(), 3);
|
||||||
}
|
}
|
||||||
Variable wrapped = wrapArgument(callLocation, invoke.getArguments().get(0),
|
Variable wrapped = wrapArgument(callLocation, invoke.getArguments().get(0),
|
||||||
|
@ -416,6 +407,12 @@ class JSClassProcessor {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String extractSuggestedPropertyName(MethodReader method) {
|
||||||
|
AnnotationReader annot = method.getAnnotations().get(JSProperty.class.getName());
|
||||||
|
AnnotationValue value = annot.getValue("value");
|
||||||
|
return value != null ? value.getString() : null;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean processIndexer(MethodReader method, CallLocation callLocation, InvokeInstruction invoke) {
|
private boolean processIndexer(MethodReader method, CallLocation callLocation, InvokeInstruction invoke) {
|
||||||
if (isProperGetIndexer(method.getDescriptor())) {
|
if (isProperGetIndexer(method.getDescriptor())) {
|
||||||
Variable result = invoke.getReceiver() != null ? program.createVariable() : null;
|
Variable result = invoke.getReceiver() != null ? program.createVariable() : null;
|
||||||
|
@ -1163,24 +1160,29 @@ class JSClassProcessor {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isProperGetter(MethodDescriptor desc) {
|
private boolean isProperGetter(MethodReader method) {
|
||||||
if (desc.parameterCount() > 0 || !typeHelper.isSupportedType(desc.getResultType())) {
|
if (method.parameterCount() > 0 || !typeHelper.isSupportedType(method.getResultType())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (desc.getResultType().equals(ValueType.BOOLEAN)) {
|
if (extractSuggestedPropertyName(method) != null) {
|
||||||
if (isProperPrefix(desc.getName(), "is")) {
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method.getResultType().equals(ValueType.BOOLEAN)) {
|
||||||
|
if (isProperPrefix(method.getName(), "is")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return isProperPrefix(desc.getName(), "get");
|
return isProperPrefix(method.getName(), "get");
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isProperSetter(MethodDescriptor desc) {
|
private boolean isProperSetter(MethodReader method) {
|
||||||
if (desc.parameterCount() != 1 || !typeHelper.isSupportedType(desc.parameterType(0))
|
if (method.parameterCount() != 1 || !typeHelper.isSupportedType(method.parameterType(0))
|
||||||
|| desc.getResultType() != ValueType.VOID) {
|
|| method.getResultType() != ValueType.VOID) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isProperPrefix(desc.getName(), "set");
|
|
||||||
|
return extractSuggestedPropertyName(method) != null || isProperPrefix(method.getName(), "set");
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isProperPrefix(String name, String prefix) {
|
private boolean isProperPrefix(String name, String prefix) {
|
||||||
|
@ -1188,7 +1190,7 @@ class JSClassProcessor {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
char c = name.charAt(prefix.length());
|
char c = name.charAt(prefix.length());
|
||||||
return Character.isUpperCase(c);
|
return Character.isUpperCase(c) || !Character.isAlphabetic(c) && Character.isJavaIdentifierStart(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isProperGetIndexer(MethodDescriptor desc) {
|
private boolean isProperGetIndexer(MethodDescriptor desc) {
|
||||||
|
@ -1201,7 +1203,7 @@ class JSClassProcessor {
|
||||||
&& typeHelper.isSupportedType(desc.parameterType(0)) && desc.getResultType() == ValueType.VOID;
|
&& typeHelper.isSupportedType(desc.parameterType(0)) && desc.getResultType() == ValueType.VOID;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String cutPrefix(String name, int prefixLength) {
|
private static String cutPrefix(String name, int prefixLength) {
|
||||||
if (name.length() == prefixLength + 1) {
|
if (name.length() == prefixLength + 1) {
|
||||||
return name.substring(prefixLength).toLowerCase();
|
return name.substring(prefixLength).toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.junit.runner.RunWith;
|
||||||
import org.teavm.jso.JSBody;
|
import org.teavm.jso.JSBody;
|
||||||
import org.teavm.jso.JSFunctor;
|
import org.teavm.jso.JSFunctor;
|
||||||
import org.teavm.jso.JSObject;
|
import org.teavm.jso.JSObject;
|
||||||
|
import org.teavm.jso.JSProperty;
|
||||||
import org.teavm.junit.SkipJVM;
|
import org.teavm.junit.SkipJVM;
|
||||||
import org.teavm.junit.TeaVMTestRunner;
|
import org.teavm.junit.TeaVMTestRunner;
|
||||||
|
|
||||||
|
@ -40,14 +41,36 @@ public class FunctorTest {
|
||||||
assertSame(firstRef, secondRef);
|
assertSame(firstRef, secondRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void propertyWithNonAlphabeticFirstChar() {
|
||||||
|
WithProperties wp = getWithPropertiesInstance();
|
||||||
|
assertEquals("foo_ok", wp.get_foo());
|
||||||
|
assertEquals("bar_ok", wp.get$bar());
|
||||||
|
assertEquals("baz_ok", wp.propbaz());
|
||||||
|
}
|
||||||
|
|
||||||
@JSBody(params = { "f", "a", "b" }, script = "return '(' + f(a, b) + ')';")
|
@JSBody(params = { "f", "a", "b" }, script = "return '(' + f(a, b) + ')';")
|
||||||
private static native String testMethod(JSBiFunction f, int a, int b);
|
private static native String testMethod(JSBiFunction f, int a, int b);
|
||||||
|
|
||||||
@JSBody(params = "f", script = "return f;")
|
@JSBody(params = "f", script = "return f;")
|
||||||
private static native JSObject getFunction(JSBiFunction f);
|
private static native JSObject getFunction(JSBiFunction f);
|
||||||
|
|
||||||
|
@JSBody(script = "return { _foo: 'foo_ok', $bar: 'bar_ok', baz: 'baz_ok' };")
|
||||||
|
private static native WithProperties getWithPropertiesInstance();
|
||||||
|
|
||||||
@JSFunctor
|
@JSFunctor
|
||||||
interface JSBiFunction extends JSObject {
|
interface JSBiFunction extends JSObject {
|
||||||
int apply(int a, int b);
|
int apply(int a, int b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface WithProperties extends JSObject {
|
||||||
|
@JSProperty
|
||||||
|
String get_foo();
|
||||||
|
|
||||||
|
@JSProperty
|
||||||
|
String get$bar();
|
||||||
|
|
||||||
|
@JSProperty("baz")
|
||||||
|
String propbaz();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user