mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -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,
|
||||
MethodHolder methodToProcess) {
|
||||
boolean[] byRefParams = new boolean[method.parameterCount()];
|
||||
boolean valid = validateSignature(method, callLocation, byRefParams);
|
||||
validateSignature(method, callLocation, byRefParams);
|
||||
if (invoke.getInstance() != null) {
|
||||
if (!typeHelper.isSupportedType(ValueType.object(method.getOwnerName()))) {
|
||||
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}}",
|
||||
invoke.getMethod(), method.getOwnerName());
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -351,8 +350,6 @@ class JSClassProcessor {
|
|||
|
||||
Variable result = invoke.getReceiver() != null ? program.createVariable() : null;
|
||||
InvokeInstruction newInvoke = new InvokeInstruction();
|
||||
ValueType[] signature = new ValueType[method.parameterCount() + 3];
|
||||
Arrays.fill(signature, ValueType.object(JSObject.class.getName()));
|
||||
newInvoke.setMethod(delegate);
|
||||
newInvoke.setType(InvocationType.SPECIAL);
|
||||
newInvoke.setReceiver(result);
|
||||
|
@ -381,12 +378,9 @@ class JSClassProcessor {
|
|||
}
|
||||
|
||||
private boolean processProperty(MethodReader method, CallLocation callLocation, InvokeInstruction invoke) {
|
||||
if (isProperGetter(method.getDescriptor())) {
|
||||
String propertyName;
|
||||
AnnotationReader annot = method.getAnnotations().get(JSProperty.class.getName());
|
||||
if (annot.getValue("value") != null) {
|
||||
propertyName = annot.getValue("value").getString();
|
||||
} else {
|
||||
if (isProperGetter(method)) {
|
||||
String propertyName = extractSuggestedPropertyName(method);
|
||||
if (propertyName == null) {
|
||||
propertyName = method.getName().charAt(0) == 'i' ? cutPrefix(method.getName(), 2)
|
||||
: cutPrefix(method.getName(), 3);
|
||||
}
|
||||
|
@ -398,12 +392,9 @@ class JSClassProcessor {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
if (isProperSetter(method.getDescriptor())) {
|
||||
String propertyName;
|
||||
AnnotationReader annot = method.getAnnotations().get(JSProperty.class.getName());
|
||||
if (annot.getValue("value") != null) {
|
||||
propertyName = annot.getValue("value").getString();
|
||||
} else {
|
||||
if (isProperSetter(method)) {
|
||||
String propertyName = extractSuggestedPropertyName(method);
|
||||
if (propertyName == null) {
|
||||
propertyName = cutPrefix(method.getName(), 3);
|
||||
}
|
||||
Variable wrapped = wrapArgument(callLocation, invoke.getArguments().get(0),
|
||||
|
@ -416,6 +407,12 @@ class JSClassProcessor {
|
|||
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) {
|
||||
if (isProperGetIndexer(method.getDescriptor())) {
|
||||
Variable result = invoke.getReceiver() != null ? program.createVariable() : null;
|
||||
|
@ -1163,24 +1160,29 @@ class JSClassProcessor {
|
|||
return null;
|
||||
}
|
||||
|
||||
private boolean isProperGetter(MethodDescriptor desc) {
|
||||
if (desc.parameterCount() > 0 || !typeHelper.isSupportedType(desc.getResultType())) {
|
||||
private boolean isProperGetter(MethodReader method) {
|
||||
if (method.parameterCount() > 0 || !typeHelper.isSupportedType(method.getResultType())) {
|
||||
return false;
|
||||
}
|
||||
if (desc.getResultType().equals(ValueType.BOOLEAN)) {
|
||||
if (isProperPrefix(desc.getName(), "is")) {
|
||||
if (extractSuggestedPropertyName(method) != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (method.getResultType().equals(ValueType.BOOLEAN)) {
|
||||
if (isProperPrefix(method.getName(), "is")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return isProperPrefix(desc.getName(), "get");
|
||||
return isProperPrefix(method.getName(), "get");
|
||||
}
|
||||
|
||||
private boolean isProperSetter(MethodDescriptor desc) {
|
||||
if (desc.parameterCount() != 1 || !typeHelper.isSupportedType(desc.parameterType(0))
|
||||
|| desc.getResultType() != ValueType.VOID) {
|
||||
private boolean isProperSetter(MethodReader method) {
|
||||
if (method.parameterCount() != 1 || !typeHelper.isSupportedType(method.parameterType(0))
|
||||
|| method.getResultType() != ValueType.VOID) {
|
||||
return false;
|
||||
}
|
||||
return isProperPrefix(desc.getName(), "set");
|
||||
|
||||
return extractSuggestedPropertyName(method) != null || isProperPrefix(method.getName(), "set");
|
||||
}
|
||||
|
||||
private boolean isProperPrefix(String name, String prefix) {
|
||||
|
@ -1188,7 +1190,7 @@ class JSClassProcessor {
|
|||
return false;
|
||||
}
|
||||
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) {
|
||||
|
@ -1201,7 +1203,7 @@ class JSClassProcessor {
|
|||
&& 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) {
|
||||
return name.substring(prefixLength).toLowerCase();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.junit.runner.RunWith;
|
|||
import org.teavm.jso.JSBody;
|
||||
import org.teavm.jso.JSFunctor;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.JSProperty;
|
||||
import org.teavm.junit.SkipJVM;
|
||||
import org.teavm.junit.TeaVMTestRunner;
|
||||
|
||||
|
@ -40,14 +41,36 @@ public class FunctorTest {
|
|||
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) + ')';")
|
||||
private static native String testMethod(JSBiFunction f, int a, int b);
|
||||
|
||||
@JSBody(params = "f", script = "return 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
|
||||
interface JSBiFunction extends JSObject {
|
||||
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