Repository: flex-falcon Updated Branches: refs/heads/develop 00db22b88 -> 88d0b23aa
Package level testing of fields and method access using chrom.js - It seems the injected static vars and instance vars in namespace classes are neccessary since the classes actually hold fields and methods. - I can type 'chrome.app.isInstalled' and 'chrome.webstore.install()' from the IDE like the google docs show when talking about how to use the chrome packages. - Where 'chrome' is a class, 'app' is a class inside the directory 'chrome' and is also a static var 'app' in the class 'chrome' and isInstalled is an instance field. - Same applies to 'webstore', install() is an instance method in the class 'webstore' located in the 'chrome' package. 'webstore' is also a static var in the 'chrome' class for dot notation access that is expected in JS. Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/5b48d61b Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/5b48d61b Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/5b48d61b Branch: refs/heads/develop Commit: 5b48d61b2b63f91d31e51a44d1f4e2dbfcfe9421 Parents: 00db22b Author: Michael Schmalle <[email protected]> Authored: Sat Jun 13 16:07:52 2015 -0400 Committer: Michael Schmalle <[email protected]> Committed: Sat Jun 13 16:07:52 2015 -0400 ---------------------------------------------------------------------- .../codegen/externals/TestExternChrome.java | 104 +++++++++++- .../codegen/externals/pass/AddMemberPass.java | 165 ++++++------------- .../externals/reference/ClassReference.java | 37 +++++ .../externals/reference/FieldReference.java | 17 +- .../externals/reference/MethodReference.java | 13 +- .../externals/reference/ReferenceModel.java | 33 +++- .../codegen/externals/utils/DebugLogUtils.java | 4 +- 7 files changed, 243 insertions(+), 130 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/5b48d61b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestExternChrome.java ---------------------------------------------------------------------- diff --git a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestExternChrome.java b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestExternChrome.java index edc9d1e..c435a03 100644 --- a/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestExternChrome.java +++ b/compiler.jx.tests/src/org/apache/flex/compiler/internal/codegen/externals/TestExternChrome.java @@ -19,11 +19,14 @@ package org.apache.flex.compiler.internal.codegen.externals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.IOException; import org.apache.flex.compiler.clients.ExternCConfiguration; +import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference; import org.junit.Test; import com.google.javascript.jscomp.Result; @@ -36,11 +39,110 @@ public class TestExternChrome extends ExternalsTestBase client.cleanOutput(); Result result = compile(); assertTrue(result.success); + + String[] classes = { + "chrome", + "chrome.app", + "chrome.webstore", + "chrome.runtime", + "chrome.runtime.lastError", + + "Port", + "ChromeEvent", + "ChromeStringEvent", + "ChromeBooleanEvent", + "ChromeNumberEvent", + "ChromeObjectEvent", + "ChromeStringArrayEvent", + "ChromeStringStringEvent", + "MessageSender", + "Tab", + "ChromeLoadTimes", + "ChromeCsiInfo" }; + + assertEquals(17, model.getClasses().size()); + for (String className : classes) + { + assertTrue(model.hasClass(className)); + } + client.emit(); } + @Test + public void test_members() throws IOException + { + client.cleanOutput(); + Result result = compile(); + assertTrue(result.success); + + // Port + ClassReference Port = model.getClassReference("Port"); + assertNotNull(Port); + assertTrue(Port.hasInstanceField("name")); + assertTrue(Port.hasInstanceField("onDisconnect")); + assertTrue(Port.hasInstanceField("onMessage")); + assertTrue(Port.hasInstanceField("sender")); + + assertTrue(Port.hasInstanceMethod("postMessage")); + assertTrue(Port.hasInstanceMethod("disconnect")); + + assertEquals("string", Port.getField("name").toTypeAnnotationString()); + assertEquals("ChromeEvent", + Port.getField("onDisconnect").toTypeAnnotationString()); + assertEquals("ChromeEvent", + Port.getField("onMessage").toTypeAnnotationString()); + assertEquals("(MessageSender|undefined)", + Port.getField("sender").toTypeAnnotationString()); + + // chrome + ClassReference chrome = model.getClassReference("chrome"); + assertNotNull(chrome); + assertTrue(chrome.hasStaticMethod("loadTimes")); + assertTrue(chrome.hasStaticMethod("csi")); + assertEquals("ChromeLoadTimes", + chrome.getMethod("loadTimes").toReturnTypeAnnotationString()); + assertEquals("ChromeCsiInfo", + chrome.getMethod("csi").toReturnTypeAnnotationString()); + + // chrome.app + ClassReference chrome_app = model.getClassReference("chrome.app"); + assertNotNull(chrome_app); + assertTrue(chrome_app.hasInstanceField("isInstalled")); + assertEquals("boolean", + chrome_app.getField("isInstalled").toTypeAnnotationString()); + + // chrome.runtime + ClassReference chrome_runtime = model.getClassReference("chrome.runtime"); + assertNotNull(chrome_runtime); + assertTrue(chrome_runtime.hasInstanceMethod("connect")); + assertTrue(chrome_runtime.hasInstanceMethod("sendMessage")); + + // chrome.runtime.lastError + ClassReference chrome_runtime_lastError = model.getClassReference("chrome.runtime.lastError"); + assertNotNull(chrome_runtime_lastError); + assertTrue(chrome_runtime_lastError.hasInstanceField("message")); + assertEquals( + "(string|undefined)", + chrome_runtime_lastError.getField("message").toTypeAnnotationString()); + + // chrome.webstore + ClassReference chrome_webstore = model.getClassReference("chrome.webstore"); + assertNotNull(chrome_webstore); + assertTrue(chrome_webstore.hasInstanceField("onInstallStageChanged")); + assertTrue(chrome_webstore.hasInstanceField("onDownloadProgress")); + assertTrue(chrome_webstore.hasInstanceMethod("install")); + + // Code generated + assertTrue(chrome.hasStaticField("app")); + assertTrue(chrome.hasStaticField("runtime")); + assertTrue(chrome.hasStaticField("webstore")); + + assertTrue(chrome_runtime.hasInstanceField("lastError")); + } + @Override - protected void configure(ExternCConfiguration config) throws IOException + protected void configure(ExternCConfiguration install) throws IOException { config.setASRoot(ExternalsTestUtils.AS_ROOT_DIR); http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/5b48d61b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java index 7213b5a..d08f9b1 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/pass/AddMemberPass.java @@ -19,7 +19,6 @@ package org.apache.flex.compiler.internal.codegen.externals.pass; -import org.apache.flex.compiler.internal.codegen.externals.reference.ClassReference; import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel; import com.google.javascript.jscomp.AbstractCompiler; @@ -75,77 +74,9 @@ public class AddMemberPass extends AbstractCompilerPass } else if (n.isGetProp()) { - //log(n.toStringTree()); - log(n.getQualifiedName()); - - String qName = n.getQualifiedName(); - // Port.prototype.name - - // chrome.runtime.lastError.message - int protoType = qName.indexOf(".prototype"); - if (protoType != -1) - { - String className = qName.substring(0, protoType); - String memberName = qName.substring(protoType + 11, - qName.length()); - log("Prototype:: className [" + className - + "] memberName [" + memberName + "]"); - model.addField(n, className, memberName); - } - else - { - String className = qName.substring(0, - qName.lastIndexOf(".")); - String memberName = qName.substring( - qName.lastIndexOf(".") + 1, qName.length()); - log("className [" + className + "] memberName [" - + memberName + "]"); - model.addStaticField(n, className, memberName); - } - - // if (n.getFirstChild().isName()) - // { - // visitStaticField(t, n); - // //System.err.println(n.toStringTree()); - // } - // else if (n.getFirstChild().isGetProp()) - // { - // try - // { - // if (n.getFirstChild().getFirstChild().isGetProp()) - // { - // // XXX TODO qualified class names 'chrome.runtime.lastError ' - // } - // else - // { - // visitInstanceField(t, n); - // } - // - // } - // catch (Exception e) - // { - // - // /* - // * - // GETPROP 438 [jsdoc_info: JSDocInfo] [source_file: [chrome]] [length: 32] - // GETPROP 438 [source_file: [chrome]] [length: 24] - // GETPROP 438 [source_file: [chrome]] [length: 14] - // NAME chrome 438 [source_file: [chrome]] [length: 6] - // STRING runtime 438 [source_file: [chrome]] [length: 7] - // STRING lastError 438 [source_file: [chrome]] [length: 9] - // STRING message 438 [source_file: [chrome]] [length: 7] - // * - // */ - // // TODO Auto-generated catch block - // System.err.println(n.toStringTree()); - // e.printStackTrace(); - // } - // } - - // System.err.println(n.toStringTree()); + visitGetProp(t, n); } } - } /* @@ -211,66 +142,66 @@ public class AddMemberPass extends AbstractCompilerPass */ // n == ASSIGN - @SuppressWarnings("unused") private void visitMethod(NodeTraversal t, Node n) { - JSDocInfo jsDoc = n.getJSDocInfo(); - if (jsDoc == null) - { - // XXX Waring - return; - } - - //System.out.println(n.toStringTree()); - Node getProp = n.getFirstChild(); - Node getProp2 = getProp.getFirstChild(); - - Node function = n.getLastChild(); + String qName = n.getFirstChild().getQualifiedName(); - Node className = getProp2.getFirstChild(); - Node prototype = getProp2.getLastChild(); // check for static - Node functionName = getProp.getLastChild(); - - //Node name = function.getChildAtIndex(0); - Node paramList = function.getChildAtIndex(1); - // if (!getProp.isQualifiedName()) - // { - // - // } - - if (getProp.getFirstChild().isGetProp()) + if (n.getFirstChild().isGetProp()) { - ClassReference classReference = model.findClassReference(className.getString()); - if (classReference != null) + int protoType = qName.indexOf(".prototype"); + if (protoType != -1) { - classReference.addMethod(n, functionName.getString(), jsDoc, - false); + String className = qName.substring(0, protoType); + String memberName = qName.substring(protoType + 11, + qName.length()); + //log("Prototype:: className [" + className + // + "] memberName [" + memberName + "]"); + model.addMethod(n, className, memberName); } else { - - err(">>>> {AddMemberPass.addMethod()} Class [" + className - + "] not found in " + n.getSourceFileName()); + String className = qName.substring(0, qName.lastIndexOf(".")); + String memberName = qName.substring(qName.lastIndexOf(".") + 1, + qName.length()); + //log("className [" + className + "] memberName [" + // + memberName + "]"); + model.addStaticMethod(n, className, memberName); } } - else if (getProp.getFirstChild().isName()) + else if (n.getFirstChild().isName()) { - className = getProp.getFirstChild(); - functionName = getProp.getLastChild(); // Same + log(n); + } + } - //System.err.println(n.toStringTree()); - ClassReference classReference = model.findClassReference(className.getString()); - if (classReference != null) - { - classReference.addMethod(n, functionName.getString(), jsDoc, - true); - } - else - { - err(">>>> {AddMemberPass.addMethod()} Class [" + className - + "] not found in " + n.getSourceFileName()); - } + private void visitGetProp(NodeTraversal t, Node n) + { + //log(n.toStringTree()); + log(n.getQualifiedName()); + + String qName = n.getQualifiedName(); + // Port.prototype.name + + // chrome.runtime.lastError.message + int protoType = qName.indexOf(".prototype"); + if (protoType != -1) + { + String className = qName.substring(0, protoType); + String memberName = qName.substring(protoType + 11, qName.length()); + //log("Prototype:: className [" + className + // + "] memberName [" + memberName + "]"); + model.addField(n, className, memberName); + } + else + { + String className = qName.substring(0, qName.lastIndexOf(".")); + String memberName = qName.substring(qName.lastIndexOf(".") + 1, + qName.length()); + //log("className [" + className + "] memberName [" + // + memberName + "]"); + model.addStaticField(n, className, memberName); } + } /* http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/5b48d61b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java index 9aa4255..880d2da 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ClassReference.java @@ -77,6 +77,11 @@ public class ClassReference extends BaseReference return methods; } + public FieldReference getField(String name) + { + return fields.get(name); + } + public MethodReference getMethod(String name) { return methods.get(name); @@ -250,11 +255,43 @@ public class ClassReference extends BaseReference return fields.containsKey(fieldName); } + public boolean hasInstanceField(String fieldName) + { + if (!fields.containsKey(fieldName)) + return false; + + return !fields.get(fieldName).isStatic(); + } + + public boolean hasStaticField(String fieldName) + { + if (!fields.containsKey(fieldName)) + return false; + + return fields.get(fieldName).isStatic(); + } + public boolean hasMethod(String methodName) { return methods.containsKey(methodName); } + public boolean hasInstanceMethod(String fieldName) + { + if (!methods.containsKey(fieldName)) + return false; + + return !methods.get(fieldName).isStatic(); + } + + public boolean hasStaticMethod(String fieldName) + { + if (!methods.containsKey(fieldName)) + return false; + + return methods.get(fieldName).isStatic(); + } + public MethodReference addMethod(Node node, String functionName, JSDocInfo comment, boolean isStatic) { http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/5b48d61b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java index cd2804a..a857260 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/FieldReference.java @@ -26,6 +26,7 @@ import org.apache.flex.compiler.internal.codegen.externals.utils.JSTypeUtils; import com.google.javascript.rhino.JSDocInfo; import com.google.javascript.rhino.JSTypeExpression; import com.google.javascript.rhino.Node; +import com.google.javascript.rhino.jstype.JSType; public class FieldReference extends MemberReference { @@ -43,6 +44,18 @@ public class FieldReference extends MemberReference this.isStatic = isStatic; } + public void setOverrideStringType(String overrideStringType) + { + this.overrideStringType = overrideStringType; + } + + public String toTypeAnnotationString() + { + JSType jsType = getComment().getType().evaluate(null, + getModel().getCompiler().getTypeRegistry()); + return jsType.toAnnotationString(); + } + public FieldReference(ReferenceModel model, ClassReference classReference, Node node, String name, JSDocInfo comment, boolean isStatic) { @@ -150,8 +163,4 @@ public class FieldReference extends MemberReference } - public void setOverrideStringType(String overrideStringType) - { - this.overrideStringType = overrideStringType; - } } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/5b48d61b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java index 0103a31..42e700a 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/MethodReference.java @@ -26,6 +26,7 @@ import org.apache.flex.compiler.internal.codegen.externals.utils.FunctionUtils; import com.google.javascript.rhino.JSDocInfo; import com.google.javascript.rhino.Node; +import com.google.javascript.rhino.jstype.JSType; public class MethodReference extends MemberReference { @@ -44,14 +45,21 @@ public class MethodReference extends MemberReference return isStatic; } + public void setStatic(boolean isStatic) + { + this.isStatic = isStatic; + } + public Set<String> getParameterNames() { return getComment().getParameterNames(); } - public void setStatic(boolean isStatic) + public String toReturnTypeAnnotationString() { - this.isStatic = isStatic; + JSType jsType = getComment().getReturnType().evaluate(null, + getModel().getCompiler().getTypeRegistry()); + return jsType.toAnnotationString(); } public MethodReference(ReferenceModel model, ClassReference classReference, @@ -177,4 +185,5 @@ public class MethodReference extends MemberReference { emitFunctionCommentBody(sb); } + } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/5b48d61b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java index 7751f4b..9d44d21 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/reference/ReferenceModel.java @@ -252,15 +252,15 @@ public class ReferenceModel constants.put(qName, reference); } - public void addField(Node node, String className, String qualfiedName) + public void addField(Node node, String className, String memberName) { ClassReference classReference = getClassReference(className); if (classReference != null) - classReference.addField(node, qualfiedName, node.getJSDocInfo(), + classReference.addField(node, memberName, node.getJSDocInfo(), false); } - public void addStaticField(Node node, String className, String qualfiedName) + public void addStaticField(Node node, String className, String memberName) { ClassReference classReference = findClassReference(className); // XXX this is here because for now, the doc might be on the parent ASSIGN node @@ -268,7 +268,32 @@ public class ReferenceModel JSDocInfo comment = NodeUtil.getBestJSDocInfo(node); if (classReference != null) { - classReference.addField(node, qualfiedName, comment, true); + classReference.addField(node, memberName, comment, true); + } + else + { + err(">>>> {ReferenceModel} Class [" + className + "] not found in " + + node.getSourceFileName()); + } + } + + public void addMethod(Node node, String className, String memberName) + { + ClassReference classReference = getClassReference(className); + if (classReference != null) + classReference.addMethod(node, memberName, node.getJSDocInfo(), + false); + } + + public void addStaticMethod(Node node, String className, String memberName) + { + ClassReference classReference = findClassReference(className); + // XXX this is here because for now, the doc might be on the parent ASSIGN node + // if it's a static property with a value + JSDocInfo comment = NodeUtil.getBestJSDocInfo(node); + if (classReference != null) + { + classReference.addMethod(node, memberName, comment, true); } else { http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/5b48d61b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java index 5dcdc48..856df40 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/externals/utils/DebugLogUtils.java @@ -23,8 +23,8 @@ import com.google.javascript.rhino.Node; public final class DebugLogUtils { - private static boolean logEnabled = false; - private static boolean errEnabled = false; + private static boolean logEnabled = true; + private static boolean errEnabled = true; public static void log(Node n) {
