Author: ptw
Date: 2008-01-08 11:41:34 -0800 (Tue, 08 Jan 2008)
New Revision: 7768
Modified:
openlaszlo/trunk/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/Parser.jjt
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/CodeGenerator.java
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/ParseTreePrinter.java
openlaszlo/trunk/test/lztest/lztest-class-impl.lzx
Log:
Change 20080108-ptw-a by [EMAIL PROTECTED] on 2008-01-08 11:56:44 EST
in /Users/ptw/OpenLaszlo/ringding-2
for http://svn.openlaszlo.org/openlaszlo/trunk
Summary: add support for `cast` keyword in javascript
Bugs Fixed:
LPP-5336 'add support for `cast` keyword in javascript'
Technical Reviewer: [EMAIL PROTECTED] (Message-Id: <[EMAIL PROTECTED]>)
QA Reviewer: [EMAIL PROTECTED] (pending)
Doc Reviewer: [EMAIL PROTECTED] (pending)
Documentation:
We now support the JS2 `cast` operator: <value> cast <type
expression>. In JS1 runtimes this is a no-op. In JS2 runtimes it
will be passed through and ensures that the value is of the correct
static type.
Details:
lztest-class-impl: Add tests suggested by Don for more complex
`is` expressions. Add tests for `cast` expressions
JavascriptGenerator, CodeGenerator, Parser, ParseTreePrinter: add
support for `cast` as a no-op (just returns the value or lhs).
Put back code that deals with null source files for now.
Tests:
lztest-class-impl
Modified:
openlaszlo/trunk/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/Parser.jjt
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/Parser.jjt
2008-01-08 18:33:30 UTC (rev 7767)
+++ openlaszlo/trunk/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/Parser.jjt
2008-01-08 19:41:34 UTC (rev 7768)
@@ -157,7 +157,6 @@
| < IF: "if" >
| < IN: "in" >
| < INSTANCEOF: "instanceof" >
-| < IS: "is" >
| < NEW: "new" >
| < RETURN: "return" >
| < SWITCH: "switch" >
@@ -181,7 +180,6 @@
| < FINAL: "final" >
| < IMPLEMENTS: "implements" >
| < IMPORT: "import" >
-| < INHERITS: "inherits" >
| < INTERFACE: "interface" >
| < INTERNAL: "internal" >
| < OVERRIDE: "override" >
@@ -190,9 +188,17 @@
| < PUBLIC: "public" >
| < STATIC: "static" >
| < SUPER: "super" >
+
+// JS2
+| < IS: "is" >
+| < CAST: "cast" >
+
+// Our extensions
+| < INHERITS: "inherits" > // obsolete
+| < MIXIN: "mixin" > // obsolete
| < TRAIT: "trait" >
-| < MIXIN: "mixin" >
+
// These are not supposed to be keywords
| < TRUE: "true" >
| < FALSE: "false" >
@@ -366,6 +372,7 @@
| t=<OVERRIDE>
| t=<DYNAMIC>
| t=<IS>
+ | t=<CAST>
)
{return t;}
}
@@ -540,7 +547,7 @@
void RelOp() #Operator : {Token t;}
{
- ("<" | ">" | "<=" | ">=" | "instanceof" | "is" | LOOKAHEAD({getAllowIn()})
"in")
+ ("<" | ">" | "<=" | ">=" | "instanceof" | "is" | "cast" |
LOOKAHEAD({getAllowIn()}) "in")
{jjtThis.setOperator(getToken(0).kind);}
}
Modified:
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/CodeGenerator.java
===================================================================
---
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/CodeGenerator.java
2008-01-08 18:33:30 UTC (rev 7767)
+++
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/CodeGenerator.java
2008-01-08 19:41:34 UTC (rev 7768)
@@ -248,7 +248,7 @@
void report(String reportMethod, SimpleNode node, Object message) {
collector.push(message);
collector.push(node.beginLine);
- collector.push(node.filename != null ? node.filename : "unknown");
+ collector.push(node.filename);
collector.push(3);
collector.push(reportMethod);
collector.emit(Instructions.CallFunction);
@@ -261,7 +261,7 @@
assert Instructions.DUP.equals(inst);
collector.push(message);
collector.push(node.beginLine);
- collector.push(node.filename != null ? node.filename : "unknown");
+ collector.push(node.filename);
collector.push(4);
collector.push(reportMethod);
collector.emit(Instructions.CallFunction);
@@ -272,7 +272,7 @@
// when called, otherwise expects the function object.
// TODO: [2006-01-04 ptw] Rewrite as a source transform
void checkUndefinedFunction(SimpleNode node, String reference) {
- if (options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES)) {
+ if (options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES) &&
node.filename != null) {
String label = newLabel(node);
collector.emit(Instructions.DUP); // ref ref
// Get the value of a function reference
@@ -297,7 +297,7 @@
// left on the stack.
// TODO: [2006-01-04 ptw] Rewrite as a source transform
void checkUndefinedMethod(SimpleNode node, String methodName) {
- if (options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES)) {
+ if (options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES) &&
node.filename != null) {
// Check that object is not undefined
String isUndefined = newLabel(node); // stack: object
collector.emit(Instructions.DUP); // stack: object, object
@@ -1596,6 +1596,13 @@
}
SimpleNode translateBinaryExpression(SimpleNode node, boolean isReferenced,
ASTOperator op, SimpleNode a, SimpleNode b) {
+ if (ParserConstants.CAST == ((ASTOperator)op).getOperator()) {
+ // Approximate a cast b as a
+ // TODO: [2008-01-08 ptw] We could typecheck and throw an error
+ // in debug mode
+ visitExpression(a);
+ return node;
+ }
visitExpression(a);
visitExpression(b);
if (ParserConstants.IS == ((ASTOperator)op).getOperator()) {
@@ -2288,7 +2295,7 @@
// fname, lineno, propertyName);
collector.push(message);
collector.push(node.beginLine);
- collector.push(node.filename != null ? node.filename : "unknown");
+ collector.push(node.filename);
collector.push(3);
collector.push(reportMethod);
collector.emit(Instructions.CallFunction);
@@ -2352,7 +2359,7 @@
// property reference. Expects the object to be at the top of stack
// when called.
protected void checkUndefinedObjectProperty(String propertyName) {
- if (options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES)) {
+ if (options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES) &&
node.filename != null) {
String label = translator.newLabel(node);
collector.emit(Instructions.DUP);
collector.emit(Instructions.TypeOf);
@@ -2371,7 +2378,7 @@
// too, hence the '==undefined' test. Expects the object member to
// be at the top of stack when called.
protected void checkUndefinedPropertySelector(String propertyName) {
- if (options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES)) {
+ if (options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES) &&
node.filename != null) {
String label = translator.newLabel(node);
collector.emit(Instructions.DUP); // s s
collector.push(Values.Undefined); // s s UNDEF
@@ -2387,7 +2394,7 @@
// Expects the object member to be at the top of stack when
// called.
protected void checkUndefinedProperty(String propertyName) {
- if (options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES)) {
+ if (options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES) &&
node.filename != null) {
String label = translator.newLabel(node);
collector.emit(Instructions.DUP);
collector.emit(Instructions.TypeOf);
@@ -2459,7 +2466,7 @@
// Expects the value of the variable to be at the top of stack when
// called.
private void checkUndefinedVariable(SimpleNode node, String variableName) {
- if (options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES)) {
+ if (options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES) &&
node.filename != null) {
String label = translator.newLabel(node);
collector.emit(Instructions.DUP);
collector.emit(Instructions.TypeOf);
Modified:
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
===================================================================
---
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
2008-01-08 18:33:30 UTC (rev 7767)
+++
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
2008-01-08 19:41:34 UTC (rev 7768)
@@ -144,7 +144,7 @@
// when called, otherwise expects the function object.
// TODO: [2006-01-04 ptw] Rewrite as a source transform
SimpleNode checkUndefinedFunction(SimpleNode node, JavascriptReference
reference) {
- if (options.getBoolean(Compiler.DEBUG) &&
options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES)) {
+ if (options.getBoolean(Compiler.DEBUG) &&
options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES) && node.filename !=
null) {
return parseFragment(
"typeof " + reference.get() + " != 'function' ? " +
report("$reportNotFunction", node, reference.get()) + " : " +
@@ -156,7 +156,7 @@
// Emits code to check that an object method is defined. Does a trial
// fetch of methodName to verify that it is a function.
SimpleNode checkUndefinedMethod(SimpleNode node, JavascriptReference
reference, String methodName) {
- if (options.getBoolean(Compiler.DEBUG) &&
options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES)) {
+ if (options.getBoolean(Compiler.DEBUG) &&
options.getBoolean(Compiler.WARN_UNDEFINED_REFERENCES) && node.filename !=
null) {
String o = newTemp();
String om = newTemp();
return parseFragment(
@@ -987,6 +987,12 @@
SimpleNode a = children[0];
SimpleNode op = children[1];
SimpleNode b = children[2];
+ if (ParserConstants.CAST == ((ASTOperator)op).getOperator()) {
+ // Approximate a cast b as a
+ // TODO: [2008-01-08 ptw] We could typecheck and throw an error
+ // in debug mode
+ return visitExpression(a);
+ }
if (ParserConstants.IS == ((ASTOperator)op).getOperator()) {
// Approximate a is b as b['$lzsc$isa'] ? b.$lzsc$isa(a) : (a
// instanceof b)
@@ -1002,7 +1008,7 @@
b instanceof ASTPropertyIdentifierReference)) {
pattern = "(_2['$lzsc$isa'] ? _2.$lzsc$isa(_1) : (_1 instanceof _2))";
} else {
- pattern = "(function (a, b) {return b['$lzsc$isa'] ? b.$lzsc$isa(a) :
(a instanceof b)})(_1, _2))";
+ pattern = "((function (a, b) {return b['$lzsc$isa'] ? b.$lzsc$isa(a) :
(a instanceof b)})(_1, _2))";
}
SimpleNode n = (new Compiler.Parser()).substitute(pattern, map);
return visitExpression(n);
Modified:
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/ParseTreePrinter.java
===================================================================
---
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/ParseTreePrinter.java
2008-01-08 18:33:30 UTC (rev 7767)
+++
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/ParseTreePrinter.java
2008-01-08 19:41:34 UTC (rev 7768)
@@ -508,7 +508,7 @@
{"*", "/", "%"},
{"+", "-"},
{"<<", ">>", ">>>"},
- {"<", "<=", ">", ">=", "instanceof", "in", "is"},
+ {"<", "<=", ">", ">=", "instanceof", "in", "is", "cast"},
{"==", "!=", "===", "!=="},
{"&"}, {"^"}, {"|"}, {"&&"}, {"||"}, {"?", ":"},
{"=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", ">>>=", "&=", "^=",
"|="},
Modified: openlaszlo/trunk/test/lztest/lztest-class-impl.lzx
===================================================================
--- openlaszlo/trunk/test/lztest/lztest-class-impl.lzx 2008-01-08 18:33:30 UTC
(rev 7767)
+++ openlaszlo/trunk/test/lztest/lztest-class-impl.lzx 2008-01-08 19:41:34 UTC
(rev 7768)
@@ -192,6 +192,19 @@
LzTestManager.assertTrue( treat is Banana, "treat is Banana" );
LzTestManager.assertEquals("/vanilla/banana/sundae", treat.initorder);
LzTestManager.assertEquals("sundae banana vanilla", treat.test());
+
+ // Additional tests to verify `is` optimizations
+ LzTestManager.assertFalse( (new Sundae()) instanceof Number );
+ LzTestManager.assertTrue( (new Number()) instanceof Number );
+ LzTestManager.assertFalse( (new Sundae()) is Number );
+ LzTestManager.assertTrue( (new Number()) is Number );
+
+ // Additional tests to verify `cast`
+ LzTestManager.assertFalse( (new Sundae()) cast Vanilla instanceof Number );
+ LzTestManager.assertTrue( (new Number()) cast Object instanceof Number );
+ LzTestManager.assertFalse( (new Sundae()) cast Vanilla is Number );
+ LzTestManager.assertTrue( (new Number()) cast Object is Number );
+
}
_______________________________________________
Laszlo-checkins mailing list
[email protected]
http://www.openlaszlo.org/mailman/listinfo/laszlo-checkins