This is an automated email from the ASF dual-hosted git repository. joshtynjala pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/royale-compiler.git
commit 485402cad211ab38c1836ea3917c3e64adf499af Author: Josh Tynjala <joshtynj...@apache.org> AuthorDate: Mon Sep 15 16:04:23 2025 -0700 compiler-jx: add missing emit for fx:RegExp tags in MXML for JS targets --- .../royale/compiler/codegen/mxml/IMXMLEmitter.java | 3 + .../internal/codegen/mxml/MXMLBlockWalker.java | 9 ++ .../internal/codegen/mxml/MXMLEmitter.java | 8 ++ .../codegen/mxml/royale/MXMLRoyaleEmitter.java | 44 +++++++ .../internal/visitor/mxml/MXMLNodeSwitch.java | 5 +- .../compiler/visitor/mxml/IMXMLBlockVisitor.java | 3 + .../mxml/royale/TestRoyaleMXMLApplication.java | 140 +++++++++++++++++++++ .../codegen/mxml/royale/TestRoyaleMXMLRegExp.java | 89 +++++++++++++ 8 files changed, 300 insertions(+), 1 deletion(-) diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/mxml/IMXMLEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/mxml/IMXMLEmitter.java index 368473eb1..a4e934439 100644 --- a/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/mxml/IMXMLEmitter.java +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/mxml/IMXMLEmitter.java @@ -42,6 +42,7 @@ import org.apache.royale.compiler.tree.mxml.IMXMLMetadataNode; import org.apache.royale.compiler.tree.mxml.IMXMLNumberNode; import org.apache.royale.compiler.tree.mxml.IMXMLObjectNode; import org.apache.royale.compiler.tree.mxml.IMXMLPropertySpecifierNode; +import org.apache.royale.compiler.tree.mxml.IMXMLRegExpNode; import org.apache.royale.compiler.tree.mxml.IMXMLRemoteObjectMethodNode; import org.apache.royale.compiler.tree.mxml.IMXMLRemoteObjectNode; import org.apache.royale.compiler.tree.mxml.IMXMLScriptNode; @@ -112,6 +113,8 @@ public interface IMXMLEmitter extends IEmitter void emitFunction(IMXMLFunctionNode node); + void emitRegExp(IMXMLRegExpNode node); + //-------------------------------------------------------------------------- void emitLiteral(IMXMLLiteralNode node); diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/MXMLBlockWalker.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/MXMLBlockWalker.java index 455044481..1863c6ef1 100644 --- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/MXMLBlockWalker.java +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/MXMLBlockWalker.java @@ -52,6 +52,7 @@ import org.apache.royale.compiler.tree.mxml.IMXMLNode; import org.apache.royale.compiler.tree.mxml.IMXMLNumberNode; import org.apache.royale.compiler.tree.mxml.IMXMLObjectNode; import org.apache.royale.compiler.tree.mxml.IMXMLPropertySpecifierNode; +import org.apache.royale.compiler.tree.mxml.IMXMLRegExpNode; import org.apache.royale.compiler.tree.mxml.IMXMLRemoteObjectMethodNode; import org.apache.royale.compiler.tree.mxml.IMXMLRemoteObjectNode; import org.apache.royale.compiler.tree.mxml.IMXMLScriptNode; @@ -361,6 +362,14 @@ public class MXMLBlockWalker implements IMXMLBlockVisitor, IMXMLBlockWalker mxmlEmitter.emitFunction(node); } + + @Override + public void visitRegExp(IMXMLRegExpNode node) + { + debug("visitRegExp()"); + + mxmlEmitter.emitRegExp(node); + } //-------------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/MXMLEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/MXMLEmitter.java index 8d3fdc3af..e4e6479cc 100644 --- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/MXMLEmitter.java +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/MXMLEmitter.java @@ -27,6 +27,7 @@ import org.apache.royale.compiler.internal.codegen.Emitter; import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens; import org.apache.royale.compiler.projects.ICompilerProject; import org.apache.royale.compiler.tree.as.IASNode; +import org.apache.royale.compiler.tree.as.IRegExpLiteralNode; import org.apache.royale.compiler.tree.mxml.*; import org.apache.royale.compiler.visitor.IBlockWalker; import org.apache.royale.compiler.visitor.mxml.IMXMLBlockWalker; @@ -307,6 +308,13 @@ public class MXMLEmitter extends Emitter implements IMXMLEmitter emitInstance(node); } + @Override + public void emitRegExp(IMXMLRegExpNode node) + { + IRegExpLiteralNode literalNode = (IRegExpLiteralNode)node.getExpressionNode(); + write(literalNode.getValue(true)); + } + //-------------------------------------------------------------------------- @Override diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java index 73000515b..ae3fb239e 100644 --- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java @@ -3380,6 +3380,28 @@ public class MXMLRoyaleEmitter extends MXMLEmitter implements } } + @Override + public void emitRegExp(IMXMLRegExpNode node) + { + if (node.getParent().getNodeID() == ASTNodeID.MXMLDeclarationsID) + { + primitiveDeclarationNodes.add(node); + return; + } + + IRegExpLiteralNode literalNode = (IRegExpLiteralNode)node.getExpressionNode(); + + MXMLDescriptorSpecifier currentDescriptor = getCurrentDescriptor("ps"); + currentDescriptor.value = literalNode.getValue(true); + + String id = node.getID(); + String localId = node.getLocalID(); + if (id != null || localId != null) + { + primitiveDeclarationNodes.add(node); + } + } + //-------------------------------------------------------------------------- @Override @@ -3978,6 +4000,28 @@ public class MXMLRoyaleEmitter extends MXMLEmitter implements write(ASEmitterTokens.SEMICOLON); break; } + case MXMLRegExpID: + { + IMXMLRegExpNode regExpNode = (IMXMLRegExpNode)declNode; + IASNode expressionNode = regExpNode.getExpressionNode(); + // it might be a binding expression instead of a literal + if (expressionNode instanceof IRegExpLiteralNode) + { + IRegExpLiteralNode literalNode = (IRegExpLiteralNode) expressionNode; + varname = regExpNode.getEffectiveID(); + writeNewline(); + write(ASEmitterTokens.THIS); + write(ASEmitterTokens.MEMBER_ACCESS); + write(varname); + write(ASEmitterTokens.SPACE); + writeToken(ASEmitterTokens.EQUAL); + IASEmitter asEmitter = ((IMXMLBlockWalker) getMXMLWalker()) + .getASEmitter(); + asEmitter.emitLiteral(literalNode); + write(ASEmitterTokens.SEMICOLON); + } + break; + } default: throw new IllegalStateException("Unknown primitive declaration node of type <" + declNode.getNodeID() diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/visitor/mxml/MXMLNodeSwitch.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/visitor/mxml/MXMLNodeSwitch.java index b5c2188bb..57bfe33a2 100644 --- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/visitor/mxml/MXMLNodeSwitch.java +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/visitor/mxml/MXMLNodeSwitch.java @@ -42,6 +42,7 @@ import org.apache.royale.compiler.tree.mxml.IMXMLMetadataNode; import org.apache.royale.compiler.tree.mxml.IMXMLNumberNode; import org.apache.royale.compiler.tree.mxml.IMXMLObjectNode; import org.apache.royale.compiler.tree.mxml.IMXMLPropertySpecifierNode; +import org.apache.royale.compiler.tree.mxml.IMXMLRegExpNode; import org.apache.royale.compiler.tree.mxml.IMXMLRemoteObjectMethodNode; import org.apache.royale.compiler.tree.mxml.IMXMLRemoteObjectNode; import org.apache.royale.compiler.tree.mxml.IMXMLScriptNode; @@ -179,6 +180,9 @@ public class MXMLNodeSwitch implements IASNodeStrategy case MXMLWebServiceOperationID: visitor.visitWebServiceMethod((IMXMLWebServiceOperationNode) node); break; + case MXMLRegExpID: + visitor.visitRegExp((IMXMLRegExpNode) node); + break; case MXMLApplicationID: case MXMLBindingAttributeID: case MXMLClassDefinitionID: @@ -192,7 +196,6 @@ public class MXMLNodeSwitch implements IASNodeStrategy case MXMLModelPropertyID: case MXMLModelRootID: case MXMLPrivateID: - case MXMLRegExpID: case MXMLReparentID: //case MXMLRepeaterID: case MXMLResourceID: diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/visitor/mxml/IMXMLBlockVisitor.java b/compiler-jx/src/main/java/org/apache/royale/compiler/visitor/mxml/IMXMLBlockVisitor.java index 55edcd34e..e79fb0b22 100644 --- a/compiler-jx/src/main/java/org/apache/royale/compiler/visitor/mxml/IMXMLBlockVisitor.java +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/visitor/mxml/IMXMLBlockVisitor.java @@ -42,6 +42,7 @@ import org.apache.royale.compiler.tree.mxml.IMXMLMetadataNode; import org.apache.royale.compiler.tree.mxml.IMXMLNumberNode; import org.apache.royale.compiler.tree.mxml.IMXMLObjectNode; import org.apache.royale.compiler.tree.mxml.IMXMLPropertySpecifierNode; +import org.apache.royale.compiler.tree.mxml.IMXMLRegExpNode; import org.apache.royale.compiler.tree.mxml.IMXMLRemoteObjectMethodNode; import org.apache.royale.compiler.tree.mxml.IMXMLRemoteObjectNode; import org.apache.royale.compiler.tree.mxml.IMXMLScriptNode; @@ -110,6 +111,8 @@ public interface IMXMLBlockVisitor extends IBlockVisitor void visitFunction(IMXMLFunctionNode node); + void visitRegExp(IMXMLRegExpNode node); + //-------------------------------------------------------------------------- void visitLiteral(IMXMLLiteralNode node); diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/royale/TestRoyaleMXMLApplication.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/royale/TestRoyaleMXMLApplication.java index dcccaedda..cb049c305 100644 --- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/royale/TestRoyaleMXMLApplication.java +++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/royale/TestRoyaleMXMLApplication.java @@ -3281,6 +3281,146 @@ public class TestRoyaleMXMLApplication extends RoyaleTestBase assertOutMXMLPostProcess(outTemplate.replaceAll("AppName", appName), true); } + @Test + public void testFXRegExpDeclaration() + { + String code = "<basic:Application xmlns:fx=\"http://ns.adobe.com/mxml/2009\" xmlns:basic=\"library://ns.apache.org/royale/basic\">" + + "<fx:Declarations><fx:RegExp id=\"foo\">/[a-z]{3,} \\d+(oz|g)/ig</fx:RegExp>" + + "</fx:Declarations><basic:initialView><basic:View><basic:DropDownList dataProvider=\"['Hello', 'World']\"/></basic:View></basic:initialView></basic:Application>"; + + IMXMLDocumentNode dnode = (IMXMLDocumentNode) getNode(code, + IMXMLDocumentNode.class, RoyaleTestBase.WRAP_LEVEL_NONE); + + ((JSRoyaleEmitter)(mxmlBlockWalker.getASEmitter())).getModel().setCurrentClass(dnode.getDefinition()); + mxmlBlockWalker.visitDocument(dnode); + String appName = dnode.getQualifiedName(); + String outTemplate = "/**\n" + + " * AppName\n" + + " *\n" + + " * @fileoverview\n" + + " *\n" + + " * @suppress {checkTypes|accessControls}\n" + + " */\n" + + "\n" + + "goog.provide('AppName');\n" + + "\n" + + "goog.require('org.apache.royale.core.Application');\n" + + "goog.require('org.apache.royale.core.View');\n" + + "goog.require('org.apache.royale.html.DropDownList');\n" + + "\n" + + "\n" + + "\n" + + "/**\n" + + " * @constructor\n" + + " * @extends {org.apache.royale.core.Application}\n" + + " */\n" + + "AppName = function() {\n" + + " AppName.base(this, 'constructor');\n" + + " \n" + + " this.foo = /[a-z]{3,}\\u0020\\d+(oz|g)/ig;\n" + + " /**\n" + + " * @private\n" + + " * @type {org.apache.royale.core.View}\n" + + " */\n" + + " this.$ID_8_1;\n" + + " \n" + + " /**\n" + + " * @private\n" + + " * @type {org.apache.royale.html.DropDownList}\n" + + " */\n" + + " this.$ID_8_0;\n" + + " \n" + + " /**\n" + + " * @private\n" + + " * @type {Array}\n" + + " */\n" + + " this.mxmldd;\n" + + " \n" + + " /**\n" + + " * @private\n" + + " * @type {Array}\n" + + " */\n" + + " this.mxmldp;\n" + + "\n" + + " this.generateMXMLAttributes([\n" + + " 1,\n" + + " 'initialView',\n" + + " false,\n" + + " [\n" + + " org.apache.royale.core.View,\n" + + " 1,\n" + + " '_id',\n" + + " true,\n" + + " '$ID_8_1',\n" + + " 0,\n" + + " 0,\n" + + " [\n" + + " org.apache.royale.html.DropDownList,\n" + + " 2,\n" + + " '_id',\n" + + " true,\n" + + " '$ID_8_0',\n" + + " 'dataProvider',\n" + + " true,\n" + + " ['Hello','World'],\n" + + " 0,\n" + + " 0,\n" + + " null\n" + + " ]\n" + + " ],\n" + + " 0,\n" + + " 0\n" + + " ]);\n" + + " \n" + + "};\n" + + "goog.inherits(AppName, org.apache.royale.core.Application);\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "/**\n" + + " * @export\n" + + " * @type {RegExp}\n" + + " */\n" + + "AppName.prototype.foo;\n" + + "\n" + + "/**\n" + + " * Metadata\n" + + " *\n" + + " * @type {Object.<string, Array.<Object>>}\n" + + " */\n" + + "AppName.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'AppName', qName: 'AppName', kind: 'class' }] };\n" + + "\n" + + "\n" + + "\n" + + "/**\n" + + " * Reflection\n" + + " *\n" + + " * @return {Object.<string, Function>}\n" + + " */\n" + + "AppName.prototype.ROYALE_REFLECTION_INFO = function () {\n" + + " return {\n" + + " variables: function () {\n" + + " return {\n" + + " 'foo': { type: 'RegExp', get_set: function (/** AppName */ inst, /** * */ v) {return v !== undefined ? inst.foo = v : inst.foo;}}\n" + + " };\n" + + " },\n" + + " methods: function () {\n" + + " return {\n" + + " 'AppName': { type: '', declaredBy: 'AppName'}\n"+ + " };\n" + + " }\n" + + " };\n" + + "};\n" + + "/**\n" + + " * @const\n" + + " * @type {number}\n" + + " */\n" + + "AppName.prototype.ROYALE_COMPILE_FLAGS = 9;"; + + assertOutMXMLPostProcess(outTemplate.replaceAll("AppName", appName), true); + } + @Test public void testFXArrayDeclaration() { diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/royale/TestRoyaleMXMLRegExp.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/royale/TestRoyaleMXMLRegExp.java new file mode 100644 index 000000000..b5efd3870 --- /dev/null +++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/mxml/royale/TestRoyaleMXMLRegExp.java @@ -0,0 +1,89 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.royale.compiler.internal.codegen.mxml.royale; + +import org.apache.royale.compiler.internal.test.RoyaleTestBase; +import org.apache.royale.compiler.tree.mxml.IMXMLDeclarationsNode; +import org.apache.royale.compiler.tree.mxml.IMXMLDocumentNode; +import org.junit.Test; + +public class TestRoyaleMXMLRegExp extends RoyaleTestBase +{ + @Test + public void testRegExpTag() + { + String code = "<fx:Declarations>\n" + + "\t<fx:RegExp id=\"regexp\">/[a-z]{3,} \\d+(oz|g)/ig</fx:RegExp>\n" + + "</fx:Declarations>"; + + IMXMLDeclarationsNode declNode = (IMXMLDeclarationsNode) getNode(code, + IMXMLDeclarationsNode.class, RoyaleTestBase.WRAP_LEVEL_DOCUMENT); + IMXMLDocumentNode docNode = (IMXMLDocumentNode) declNode.getAncestorOfType(IMXMLDocumentNode.class); + mxmlBlockWalker.visitDocument(docNode); + + String appName = docNode.getQualifiedName(); + + String outTemplate = "/**\n" + + " * AppName\n" + + " *\n" + + " * @fileoverview\n" + + " *\n" + + " * @suppress {checkTypes|accessControls}\n" + + " */\n" + + "\n" + + "goog.provide('AppName');\n" + + "\n" + + "goog.require('org.apache.royale.core.Application');\n" + + "\n" + + "\n" + + "\n" + + "/**\n" + + " * @constructor\n" + + " * @extends {org.apache.royale.core.Application}\n" + + " */\n" + + "AppName = function() {\n" + + " AppName.base(this, 'constructor');\n" + + " \n" + + " this.regexp = /[a-z]{3,}\\u0020\\d+(oz|g)/ig;\n" + + " /**\n" + + " * @private\n" + + " * @type {Array}\n" + + " */\n" + + " this.mxmldd;\n" + + " \n" + + " /**\n" + + " * @private\n" + + " * @type {Array}\n" + + " */\n" + + " this.mxmldp;\n" + + "};\n" + + "goog.inherits(AppName, org.apache.royale.core.Application);\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "/**\n" + + " * @export\n" + + " * @type {RegExp}\n" + + " */\n" + + "AppName.prototype.regexp;"; + + assertOut(outTemplate.replaceAll("AppName", appName), false); + } +}