Author: dda
Date: 2007-12-06 12:37:08 -0800 (Thu, 06 Dec 2007)
New Revision: 7476
Added:
openlaszlo/trunk/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/parser/ASTModifiedDefinition.java
Modified:
openlaszlo/trunk/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/Parser.jjt
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/js2doc/JS2Doc.java
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/CodeGenerator.java
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/CommonGenerator.java
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
Log:
Change 20071205-dda-z by [EMAIL PROTECTED] on 2007-12-05 10:32:16 EST
in /Users/dda/laszlo/src/svn/openlaszlo/trunk
for http://svn.openlaszlo.org/openlaszlo/trunk
Summary: Initial support for keywords in script compiler
New Features: no exposed features yet
Bugs Fixed: LPP-5175
Technical Reviewer: ptw
QA Reviewer: hminsky
Doc Reviewer: (pending)
Documentation:
Nothing here affects .lzx files, and even for lzs coders, there is no effect
unless the new keywords are used. Even so -- they don't do anything for
SWF8/9,DHTML,
they are merely accepted.. Some of these keywords will be used internally
to help implement SWF9 (in later reviews), some may be exposed to users
indirectly
via .lzx tags in the future, at which time they may be documented.
All keywords used in accordance with ActionScript 3.0 and the Ecmascript
draft standard.
Release Notes:
None.
Details:
Initial support for several JS2 keywords: 'dynamic', 'override', 'final',
'private', 'protected', 'public', 'internal'. The keyword 'static',
although previously
supported, is now handled in same way as the new group. In fact new
keyword modifiers (I just
noticed const) should now be easy to add. These keywords are all modifiers,
in that they appear as part of a function, class, var definition, before
the keywords 'function', 'class', 'var'. Multiple keywords can
of course appear, for example, 'public static var x;'
Also name space names can appear in this position, for example,
mynamespace function f1() { }
final override mynamespace function f2() { }
There is no specific ordering of keywords enforced, and there are few
restrictions: override is only for methods, dynamic is only for classes,
only a single namespace name can appear, and a namespace cannot appear
along with a visibility modifier ('public', 'private', 'protected',
'internal').
By 'initial support', I mean that the keywords are now accepted, in the
proper
place and the infrastructure is available to take advantage of them.
For SWF9, we plan to implement most or all of these keywords.
Any code in the compilers or doc tools that already knew about 'static',
has been changed to use this new modifier class.
To make for easy handling of these modifiers (and potentially new ones),
there
is a new AST type: ASTModifiedDefinition. This can generally appear in
the AST
wherever a ClassDefinition, FunctionDeclaration or VariableStatement
appears,
and it has a child which is the ClassDefinition, FunctionDeclaration,
VariableStatement.
There is only one of these objects in the tree for any
definition/declaration,
and it holds information about all modifiers, including namespace names for
the
given declaration. This should make it easy to change any specifics about
the modifiers, which ones are supported, etc. and allows each runtime to
make
its own decisions about how to treat the modifiers.
Tests:
smoketest for SWF7/8 and DHTML
exact comparison of LFC binaries (using 'generatePredictableTemps' option)
comparison of JS2doc outputs for representative classes
to ensure that no visible changes.
A basic .lzs test to test that various keyword combinations are
accepted/rejected.
since 'test/' directory does not have .lzs files, I only include it here:
///////////////////////
// tests for new script compiler keywords
// to test keyword combinations that should
// give errors, uncomment lines beginning with //XXXX
function f1() { }
static function f2() { }
private static function f3() { }
static protected function f4() { }
static override function f5() { }
ns1 function f6() { }
ns1 final function f7() { }
final ns1 function f8() { }
var v1;
// Not allowed outside of class:
//XXXX public var badv1;
//XXXX static var badv2;
//XXXX protected static var badv3;
class c1 {
function cf1() { }
static function cf2() { }
private static function cf3() { }
static protected function cf4() { }
static override function cf5() { }
ns1 function cf6() { }
ns1 final function cf7() { }
final ns1 function cf8() { }
var cv1;
public var cv2;
static var cv3;
protected static var cv4;
}
private class c2 {}
ns2 class c3 {}
dynamic class c4 {}
// Multiple namespace names not allowed
//XXXX ns1 ns2 class badc1{}
// namespace not allowed with public/private/etc.
//XXXX public ns1 class badc2{}
//XXXX ns2 protected class badc3{}
// Inappropriate combinations
//XXXX override var badv4;
//XXXX dynamic function badf1() {}
//XXXX dynamic var badv5;
//XXXX override class badc4{}
///////////////////////
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
2007-12-06 20:11:13 UTC (rev 7475)
+++ openlaszlo/trunk/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/Parser.jjt
2007-12-06 20:37:08 UTC (rev 7476)
@@ -173,6 +173,7 @@
| < CLASS: "class" >
| < CONST: "const" >
| < DEBUGGER: "debugger" >
+| < DYNAMIC: "dynamic" >
| < ENUM: "enum" >
| < EXPORT: "export" >
| < EXTENDS: "extends" >
@@ -181,6 +182,11 @@
| < IMPORT: "import" >
| < INHERITS: "inherits" >
| < INTERFACE: "interface" >
+| < INTERNAL: "internal" >
+| < OVERRIDE: "override" >
+| < PRIVATE: "private" >
+| < PROTECTED: "protected" >
+| < PUBLIC: "public" >
| < STATIC: "static" >
| < SUPER: "super" >
| < TRAIT: "trait" >
@@ -868,13 +874,17 @@
{ return jjtThis; }
}
+void ModifiedDefinition() #ModifiedDefinition : {}
+{
+ Modifiers(jjtThis) (FunctionDeclaration() | ClassDefinition())
+}
+
void Directive() #void : {}
{
// Lookahead so that 'function' begins a function declaration,
// not a function expression.
- LOOKAHEAD(1)
- FunctionDeclaration()
-| ClassDefinition()
+ LOOKAHEAD(ModifiedDefinition())
+ ModifiedDefinition()
| LOOKAHEAD("{") DirectiveBlock()
| (ToplevelStatement()) #Statement
| LOOKAHEAD(2) IncludeDirective() Sc()
@@ -889,7 +899,7 @@
SimpleNode StatementList() #StatementList : {Token t;}
{
- ( ClassDefinition() | LOOKAHEAD(1) FunctionDeclaration() | Statement() |
PragmaDirective())+
+ ( LOOKAHEAD(ModifiedDefinition()) ModifiedDefinition() | Statement() |
PragmaDirective())+
{ return jjtThis; }
}
@@ -917,9 +927,9 @@
// TBD: verify that the next token isn't a line break
}
-SimpleNode ClassProperty() #ClassProperty : {Token t;}
+SimpleNode ClassProperty() #ModifiedDefinition : {}
{
- "static" (FunctionDeclaration() | VariableStatement())
+ Modifiers(jjtThis) (FunctionDeclaration() | VariableStatement())
{return jjtThis; }
}
@@ -938,9 +948,7 @@
void ClassDirective() #void : {}
{
- ClassProperty()
- | LOOKAHEAD(1) FunctionDeclaration()
- | LOOKAHEAD(1) VariableStatement()
+ LOOKAHEAD(ClassProperty()) ClassProperty()
| LOOKAHEAD("{") ClassDirectiveBlock()
| (ToplevelStatement()) #Statement
| PragmaDirective() Sc()
@@ -970,3 +978,30 @@
)* "}"
{return jjtThis;}
}
+
+void Modifiers(ASTModifiedDefinition mod): { Token t; }
+{
+ (
+ LOOKAHEAD(2)
+ (
+ t = <IDENTIFIER>
+ {mod.setToken(t).setNamespace(t.image); }
+ | t = "public"
+ {mod.setToken(t).setAccess(ASTAccessModifier.PUBLIC_ACCESS);}
+ | t = "protected"
+ {mod.setToken(t).setAccess(ASTAccessModifier.PROTECTED_ACCESS);}
+ | t = "internal"
+ {mod.setToken(t).setAccess(ASTAccessModifier.INTERNAL_ACCESS);}
+ | t = "private"
+ {mod.setToken(t).setAccess(ASTAccessModifier.PRIVATE_ACCESS);}
+ | t = "static"
+ {mod.setToken(t).setStatic(true);}
+ | t = "final"
+ {mod.setToken(t).setFinal(true);}
+ | t = "dynamic"
+ {mod.setToken(t).setDynamic(true);}
+ | t = "override"
+ {mod.setToken(t).setOverride(true);}
+ )
+ )*
+}
Added:
openlaszlo/trunk/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/parser/ASTModifiedDefinition.java
Property changes on:
openlaszlo/trunk/WEB-INF/lps/server/sc/src/org/openlaszlo/sc/parser/ASTModifiedDefinition.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Modified:
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/js2doc/JS2Doc.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/js2doc/JS2Doc.java
2007-12-06 20:11:13 UTC (rev 7475)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/js2doc/JS2Doc.java
2007-12-06 20:37:08 UTC (rev 7476)
@@ -97,13 +97,15 @@
} else if (parseNode instanceof ASTFunctionDeclaration) {
visitFunctionDeclaration(parseNode, docNode);
} else if (parseNode instanceof ASTClassDefinition) {
- visitClassDeclaration(parseNode, docNode);
+ visitClassDeclaration(parseNode, docNode, null);
} else if (parseNode instanceof ASTIfDirective) {
visitTopLevelIfDirective(parseNode, docNode);
} else if (parseNode instanceof ASTIncludeDirective) {
visitIncludeDirective(parseNode, docNode, true);
} else if (parseNode instanceof ASTCallExpression) {
visitCallExpression(parseNode, docNode);
+ } else if (parseNode instanceof ASTModifiedDefinition) {
+ visitModifiedDefinition(parseNode, docNode);
} else if (parseNode instanceof ASTPragmaDirective) {
// do nothing
} else {
@@ -317,16 +319,18 @@
logger.warning("tried to redefine function but couldn't
resolve function name");
}
- protected void visitClassDeclaration(SimpleNode parseNode,
org.w3c.dom.Element docNode) {
+ protected void visitClassDeclaration(SimpleNode parseNode,
org.w3c.dom.Element docNode, ASTModifiedDefinition moddef) {
SimpleNode[] children = parseNode.getChildren();
checkChildrenLowerBounds(parseNode, 2, 0, "visitClassDefinition");
ASTIdentifier nameNode = (ASTIdentifier) children[1];
String className = nameNode.getName();
+ SimpleNode parseNodeForDoc = (moddef != null) ? moddef : parseNode;
+
PropertyReference propRef = new PropertyReference(docNode,
className, this.currentState);
- org.w3c.dom.Element property =
propRef.redefineProperty(parseNode.getComment());
+ org.w3c.dom.Element property =
propRef.redefineProperty(parseNodeForDoc.getComment());
if (this.unitID != null)
property.setAttribute("unitid", unitID);
@@ -347,7 +351,7 @@
final int n = children.length;
for (int i=4; i<n; i++) {
SimpleNode decl = children[i];
- this.visitClassStatement(decl, classNode);
+ this.visitClassStatement(decl, classNode, null);
}
} finally {
this.objectID = oldObjectID;
@@ -356,19 +360,17 @@
}
}
- protected void visitClassStatement(SimpleNode parseNode,
org.w3c.dom.Element docNode) {
+ protected void visitClassStatement(SimpleNode parseNode,
org.w3c.dom.Element docNode, ASTModifiedDefinition moddef) {
if (parseNode instanceof ASTStatement ||
parseNode instanceof ASTClassDirectiveBlock) {
SimpleNode[] children = parseNode.getChildren();
for (int i = 0; i < children.length; i++) {
- this.visitClassStatement(children[i], docNode);
+ this.visitClassStatement(children[i], docNode, null);
}
} else if (parseNode instanceof ASTVariableStatement) {
- visitFieldStatement(parseNode, docNode, false, null);
+ visitFieldStatement(parseNode, docNode, moddef, null);
} else if (parseNode instanceof ASTFunctionDeclaration) {
- visitMethodDeclaration(parseNode, docNode, false, null);
- } else if (parseNode instanceof ASTClassProperty) {
- visitClassProperty(parseNode, docNode);
+ visitMethodDeclaration(parseNode, docNode, moddef, null);
} else if (parseNode instanceof ASTCallExpression) {
visitCallExpression(parseNode, docNode);
} else if (parseNode instanceof ASTAssignmentExpression) {
@@ -377,6 +379,8 @@
visitClassIfDirective(parseNode, docNode);
} else if (parseNode instanceof ASTIncludeDirective) {
visitIncludeDirective(parseNode, docNode, false);
+ } else if (parseNode instanceof ASTModifiedDefinition) {
+ visitModifiedDefinition(parseNode, docNode);
} else if (parseNode instanceof ASTPragmaDirective) {
// do nothing
} else {
@@ -384,12 +388,12 @@
}
}
- protected void visitFieldStatement(SimpleNode parseNode,
org.w3c.dom.Element docNode, boolean isStatic, String commonComment) {
+ protected void visitFieldStatement(SimpleNode parseNode,
org.w3c.dom.Element docNode, ASTModifiedDefinition moddef, String
commonComment) {
VariableDeclarationsInfo decls =
collectVariableDeclarations(parseNode);
String comment = (decls.commonComment != null) ?
decls.commonComment : commonComment;
SimpleNode[] vars = decls.variables;
for (int i = 0; i < vars.length; i++) {
- this.visitFieldDeclaration(vars[i], docNode, comment,
isStatic);
+ this.visitFieldDeclaration(vars[i], docNode, comment,
moddef.isStatic());
}
}
@@ -440,7 +444,7 @@
}
}
- protected void visitMethodDeclaration(SimpleNode parseNode,
org.w3c.dom.Element docNode, boolean isStatic, String comment) {
+ protected void visitMethodDeclaration(SimpleNode parseNode,
org.w3c.dom.Element docNode, ASTModifiedDefinition moddef, String comment) {
SimpleNode[] children = parseNode.getChildren();
checkChildrenLowerBounds(parseNode, 3, 3,
"visitMethodDeclaration");
@@ -449,7 +453,7 @@
org.w3c.dom.Element targetNode = docNode;
- if (isStatic == false)
+ if (moddef.isStatic() == false)
targetNode = this.ensurePrototypeNode(docNode);
if (targetNode != null) {
@@ -468,17 +472,20 @@
}
}
- protected void visitClassProperty(SimpleNode parseNode,
org.w3c.dom.Element docNode) {
+ protected void visitModifiedDefinition(SimpleNode parseNode,
org.w3c.dom.Element docNode) {
SimpleNode[] children = parseNode.getChildren();
- checkChildrenLowerBounds(parseNode, 1, 1, "visitClassProperty");
+ checkChildrenLowerBounds(parseNode, 1, 1,
"visitModifiedDefinition");
String comment = parseNode.getComment();
+ ASTModifiedDefinition moddef = (ASTModifiedDefinition)parseNode;
SimpleNode child = children[0];
if (child instanceof ASTVariableStatement)
- this.visitFieldStatement(child, docNode, true, comment);
+ this.visitFieldStatement(child, docNode, moddef, comment);
else if (child instanceof ASTFunctionDeclaration)
- this.visitMethodDeclaration(child, docNode, true, comment);
+ this.visitMethodDeclaration(child, docNode, moddef, comment);
+ else if (child instanceof ASTClassDefinition)
+ this.visitClassDeclaration(child, docNode, moddef);
else
throw new InternalError("Unexpected node type " +
parseNode.getClass().getName(), parseNode);
}
@@ -624,7 +631,7 @@
if (isTopLevel)
this.visitToplevelStatement(trueDirective, docNode);
else
- this.visitClassStatement(trueDirective, docNode);
+ this.visitClassStatement(trueDirective, docNode, null);
} finally {
this.currentState = previousState;
}
@@ -647,7 +654,7 @@
if (isTopLevel)
this.visitToplevelStatement(condChild,
docNode);
else
- this.visitClassStatement(condChild, docNode);
+ this.visitClassStatement(condChild, docNode,
null);
}
} finally {
this.currentState = previousState;
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
2007-12-06 20:11:13 UTC (rev 7475)
+++
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/CodeGenerator.java
2007-12-06 20:37:08 UTC (rev 7476)
@@ -436,6 +436,8 @@
visitStatement(directive);
} else if (directive instanceof ASTClassDefinition) {
visitClassDefinition(directive, directive.getChildren());
+ } else if (directive instanceof ASTModifiedDefinition) {
+ visitModifiedDefinition(directive, directive.getChildren());
} else if (directive instanceof ASTStatement) {
// Statements are processed in pass 1 for now
visitStatement(directive);
Modified:
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/CommonGenerator.java
===================================================================
---
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/CommonGenerator.java
2007-12-06 20:11:13 UTC (rev 7475)
+++
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/CommonGenerator.java
2007-12-06 20:37:08 UTC (rev 7476)
@@ -392,9 +392,17 @@
for (int i = 0; i < dirs.length; i++) {
SimpleNode n = dirs[i];
List p = props;
- if (n instanceof ASTClassProperty) {
+
+ // any modifiers, like 'static', 'final' are kept in mod.
+ ASTModifiedDefinition mod = null;
+ if (n instanceof ASTModifiedDefinition) {
+ assert (n.getChildren().length == 1);
+ mod = (ASTModifiedDefinition)n;
+ if (mod.isStatic()) {
+ p = classProps;
+ }
n = n.get(0);
- p = classProps;
+ mod.verifyClassLevel(n);
}
if (n instanceof ASTFunctionDeclaration) {
SimpleNode[] c = n.getChildren();
@@ -542,6 +550,9 @@
else if (node instanceof ASTSwitchStatement) {
newNode = visitSwitchStatement(node, children);
}
+ else if (node instanceof ASTModifiedDefinition) {
+ newNode = visitModifiedDefinition(node, children);
+ }
else if (node instanceof Compiler.PassThroughNode) {
newNode = node;
} else {
@@ -592,6 +603,18 @@
return visitStatementList(node, children);
}
+ public SimpleNode visitModifiedDefinition(SimpleNode node, SimpleNode[]
children) {
+ // Modifiers, like 'final', are ignored unless this is handled
+ // by the runtime.
+
+ assert children.length == 1;
+ SimpleNode child = children[0];
+
+ ((ASTModifiedDefinition)node).verifyTopLevel(child);
+
+ return visitStatement(child);
+ }
+
public SimpleNode visitLabeledStatement(SimpleNode node, SimpleNode[]
children) {
ASTIdentifier name = (ASTIdentifier)children[0];
SimpleNode stmt = children[1];
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
2007-12-06 20:11:13 UTC (rev 7475)
+++
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
2007-12-06 20:37:08 UTC (rev 7476)
@@ -279,6 +279,8 @@
newDirective = visitStatement(directive);
} else if (directive instanceof ASTClassDefinition) {
newDirective = visitStatement(directive);
+ } else if (directive instanceof ASTModifiedDefinition) {
+ newDirective = visitModifiedDefinition(directive,
directive.getChildren());
} else if (directive instanceof ASTStatement) {
// Statements are processed in pass 1 for now
newDirective = visitStatement(directive);
_______________________________________________
Laszlo-checkins mailing list
[email protected]
http://www.openlaszlo.org/mailman/listinfo/laszlo-checkins