This is an automated email from the ASF dual-hosted git repository.
Harbs pushed a commit to branch codegraph
in repository https://gitbox.apache.org/repos/asf/royale-compiler.git
The following commit(s) were added to refs/heads/codegraph by this push:
new 0ba4d648e Add metadata handling to Code Graph: implement metadata
classes and update exporter and writer
0ba4d648e is described below
commit 0ba4d648e1acaa8106bccb1c51a590a0eb2d94b2
Author: Harbs <[email protected]>
AuthorDate: Fri Jul 31 14:28:07 2026 +0300
Add metadata handling to Code Graph: implement metadata classes and update
exporter and writer
---
.../internal/codegen/graph/CodeGraphExporter.java | 20 ++++++++
.../internal/codegen/graph/CodeGraphMetadata.java | 53 ++++++++++++++++++++++
.../codegen/graph/CodeGraphMetadataAttribute.java | 45 ++++++++++++++++++
.../internal/codegen/graph/CodeGraphSymbol.java | 11 +++++
.../internal/codegen/graph/CodeGraphWriter.java | 52 +++++++++++++++++++++
.../codegen/graph/TestCodeGraphExporter.java | 24 ++++++++++
.../codegen/graph/TestCodeGraphWriter.java | 5 ++
.../test/resources/codegraph/golden/GraphBase.as | 1 +
.../test/resources/codegraph/golden/GraphRoot.as | 2 +
.../test/resources/codegraph/golden/GraphRoot.json | 37 ++++++++++++++-
10 files changed, 249 insertions(+), 1 deletion(-)
diff --git
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphExporter.java
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphExporter.java
index a8968197d..eed8e2ca9 100644
---
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphExporter.java
+++
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphExporter.java
@@ -37,6 +37,8 @@ import
org.apache.royale.compiler.definitions.IParameterDefinition;
import org.apache.royale.compiler.definitions.ISetterDefinition;
import org.apache.royale.compiler.definitions.ITypeDefinition;
import org.apache.royale.compiler.definitions.IVariableDefinition;
+import org.apache.royale.compiler.definitions.metadata.IMetaTag;
+import org.apache.royale.compiler.definitions.metadata.IMetaTagAttribute;
import org.apache.royale.compiler.projects.ICompilerProject;
public final class CodeGraphExporter
@@ -82,6 +84,7 @@ public final class CodeGraphExporter
private CodeGraphSymbol exportType(ITypeDefinition definition)
{
CodeGraphSymbol symbol = createSymbol(definition,
getTypeKind(definition));
+ addMetadata(symbol, definition);
if (definition instanceof IClassDefinition)
{
IClassDefinition classDefinition = (IClassDefinition)definition;
@@ -137,6 +140,7 @@ public final class CodeGraphExporter
CodeGraphSymbol symbol = new CodeGraphSymbol(id,
definition.getQualifiedName(), definition.getBaseName(),
definition.getPackageName(), kind);
+ addMetadata(symbol, definition);
symbol.setDeclaringType(createReference(declaringType));
if (definition instanceof IGetterDefinition || definition instanceof
ISetterDefinition)
{
@@ -182,6 +186,7 @@ public final class CodeGraphExporter
CodeGraphSymbol symbol = new CodeGraphSymbol(
CodeGraphIdFactory.member(declaringType.getQualifiedName(),
definition.getBaseName()),
definition.getQualifiedName(), definition.getBaseName(),
definition.getPackageName(), kind);
+ addMetadata(symbol, definition);
symbol.setDeclaringType(createReference(declaringType));
ITypeDefinition typeDefinition = definition.resolveType(project);
if (typeDefinition != null)
@@ -200,6 +205,21 @@ public final class CodeGraphExporter
return definition instanceof IClassDefinition ? "class" : "interface";
}
+ private void addMetadata(CodeGraphSymbol symbol, IDefinition definition)
+ {
+ for (IMetaTag metaTag : definition.getAllMetaTags())
+ {
+ if (IMetaTag.GO_TO_DEFINITION_HELP.equals(metaTag.getTagName()))
+ continue;
+ CodeGraphMetadata metadata = new
CodeGraphMetadata(metaTag.getTagName());
+ for (IMetaTagAttribute attribute : metaTag.getAllAttributes())
+ {
+ metadata.addAttribute(new
CodeGraphMetadataAttribute(attribute.getKey(), attribute.getValue()));
+ }
+ symbol.addMetadata(metadata);
+ }
+ }
+
private CodeGraphReference createReference(ITypeDefinition definition)
{
String qualifiedName = definition.getQualifiedName();
diff --git
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphMetadata.java
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphMetadata.java
new file mode 100644
index 000000000..a55a68ff7
--- /dev/null
+++
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphMetadata.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.graph;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * An ActionScript metadata annotation and its ordered arguments.
+ */
+public final class CodeGraphMetadata
+{
+ private final String name;
+ private final List<CodeGraphMetadataAttribute> attributes = new
ArrayList<CodeGraphMetadataAttribute>();
+
+ public CodeGraphMetadata(String name)
+ {
+ this.name = name;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void addAttribute(CodeGraphMetadataAttribute attribute)
+ {
+ attributes.add(attribute);
+ }
+
+ public List<CodeGraphMetadataAttribute> getAttributes()
+ {
+ return Collections.unmodifiableList(attributes);
+ }
+}
\ No newline at end of file
diff --git
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphMetadataAttribute.java
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphMetadataAttribute.java
new file mode 100644
index 000000000..3f2c7b364
--- /dev/null
+++
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphMetadataAttribute.java
@@ -0,0 +1,45 @@
+/*
+ *
+ * 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.graph;
+
+/**
+ * An ordered key/value argument in an ActionScript metadata annotation.
+ */
+public final class CodeGraphMetadataAttribute
+{
+ private final String key;
+ private final String value;
+
+ public CodeGraphMetadataAttribute(String key, String value)
+ {
+ this.key = key;
+ this.value = value;
+ }
+
+ public String getKey()
+ {
+ return key;
+ }
+
+ public String getValue()
+ {
+ return value;
+ }
+}
\ No newline at end of file
diff --git
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphSymbol.java
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphSymbol.java
index aa860608a..ff940c8c5 100644
---
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphSymbol.java
+++
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphSymbol.java
@@ -38,6 +38,7 @@ public final class CodeGraphSymbol
private CodeGraphReference baseType;
private final List<CodeGraphReference> interfaces = new
ArrayList<CodeGraphReference>();
private final List<CodeGraphParameter> parameters = new
ArrayList<CodeGraphParameter>();
+ private final List<CodeGraphMetadata> metadata = new
ArrayList<CodeGraphMetadata>();
private final List<CodeGraphSymbol> members = new
ArrayList<CodeGraphSymbol>();
public CodeGraphSymbol(String id, String qualifiedName, String baseName,
String packageName, String kind)
@@ -154,6 +155,16 @@ public final class CodeGraphSymbol
return Collections.unmodifiableList(parameters);
}
+ public void addMetadata(CodeGraphMetadata metadataTag)
+ {
+ metadata.add(metadataTag);
+ }
+
+ public List<CodeGraphMetadata> getMetadata()
+ {
+ return Collections.unmodifiableList(metadata);
+ }
+
public void addMember(CodeGraphSymbol member)
{
members.add(member);
diff --git
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphWriter.java
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphWriter.java
index af83ffd74..05d86fc32 100644
---
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphWriter.java
+++
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/graph/CodeGraphWriter.java
@@ -102,6 +102,10 @@ public final class CodeGraphWriter
{
writeParameters(writer, symbol.getParameters(), level + 1,
--optionalPropertyCount > 0);
}
+ if (!symbol.getMetadata().isEmpty())
+ {
+ writeMetadata(writer, symbol.getMetadata(), level + 1,
--optionalPropertyCount > 0);
+ }
if (!symbol.getMembers().isEmpty())
writeSymbols(writer, "members", symbol.getMembers(), level + 1,
false);
indent(writer, level);
@@ -127,6 +131,8 @@ public final class CodeGraphWriter
result++;
if (!symbol.getParameters().isEmpty())
result++;
+ if (!symbol.getMetadata().isEmpty())
+ result++;
if (!symbol.getMembers().isEmpty())
result++;
return result;
@@ -208,6 +214,52 @@ public final class CodeGraphWriter
writer.write('\n');
}
+ private void writeMetadata(Writer writer, List<CodeGraphMetadata>
metadata, int level, boolean comma)
+ throws IOException
+ {
+ indent(writer, level);
+ writeString(writer, "metadata");
+ writer.write(": [\n");
+ for (int i = 0; i < metadata.size(); i++)
+ {
+ CodeGraphMetadata metadataTag = metadata.get(i);
+ indent(writer, level + 1);
+ writer.write("{\n");
+ writeProperty(writer, level + 2, "name", metadataTag.getName(),
true);
+ indent(writer, level + 2);
+ writeString(writer, "attributes");
+ writer.write(": [");
+ if (!metadataTag.getAttributes().isEmpty())
+ writer.write('\n');
+ for (int j = 0; j < metadataTag.getAttributes().size(); j++)
+ {
+ CodeGraphMetadataAttribute attribute =
metadataTag.getAttributes().get(j);
+ indent(writer, level + 3);
+ writer.write("{\n");
+ writeProperty(writer, level + 4, "key", attribute.getKey(),
true);
+ writeProperty(writer, level + 4, "value",
attribute.getValue(), false);
+ indent(writer, level + 3);
+ writer.write('}');
+ if (j + 1 < metadataTag.getAttributes().size())
+ writer.write(',');
+ writer.write('\n');
+ }
+ if (!metadataTag.getAttributes().isEmpty())
+ indent(writer, level + 2);
+ writer.write("]\n");
+ indent(writer, level + 1);
+ writer.write('}');
+ if (i + 1 < metadata.size())
+ writer.write(',');
+ writer.write('\n');
+ }
+ indent(writer, level);
+ writer.write(']');
+ if (comma)
+ writer.write(',');
+ writer.write('\n');
+ }
+
private void writeBooleanProperty(Writer writer, int level, String name,
boolean value, boolean comma)
throws IOException
{
diff --git
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/graph/TestCodeGraphExporter.java
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/graph/TestCodeGraphExporter.java
index fffd523b4..0f3619ec2 100644
---
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/graph/TestCodeGraphExporter.java
+++
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/graph/TestCodeGraphExporter.java
@@ -22,9 +22,11 @@ package org.apache.royale.compiler.internal.codegen.graph;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.Collections;
+import java.util.List;
import org.apache.royale.compiler.internal.test.ASTestBase;
import org.apache.royale.compiler.tree.as.IClassNode;
@@ -99,6 +101,28 @@ public class TestCodeGraphExporter extends ASTestBase
assertTrue(method.getParameters().get(2).isRest());
}
+ @Test
+ public void testMetadataAndAttributesAreCollectedInOrder()
+ {
+ IClassNode classNode = getClassNode("[Event(name=\"change\",
type=\"example.ChangeEvent\")]"
+ + "[Bindable(\"selected\")]"
+ + "public class Widget {}");
+
+ CodeGraphModel model = new CodeGraphExporter(project).export(
+ Collections.singleton(classNode.getDefinition()), "js", null);
+ List<CodeGraphMetadata> metadata =
model.getSymbols().get(0).getMetadata();
+
+ assertEquals(2, metadata.size());
+ assertEquals("Event", metadata.get(0).getName());
+ assertEquals("name", metadata.get(0).getAttributes().get(0).getKey());
+ assertEquals("change",
metadata.get(0).getAttributes().get(0).getValue());
+ assertEquals("type", metadata.get(0).getAttributes().get(1).getKey());
+ assertEquals("example.ChangeEvent",
metadata.get(0).getAttributes().get(1).getValue());
+ assertEquals("Bindable", metadata.get(1).getName());
+ assertNull(metadata.get(1).getAttributes().get(0).getKey());
+ assertEquals("selected",
metadata.get(1).getAttributes().get(0).getValue());
+ }
+
private CodeGraphSymbol findMember(CodeGraphSymbol owner, String kind)
{
for (CodeGraphSymbol member : owner.getMembers())
diff --git
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/graph/TestCodeGraphWriter.java
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/graph/TestCodeGraphWriter.java
index 43cded64a..96ce598ae 100644
---
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/graph/TestCodeGraphWriter.java
+++
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/graph/TestCodeGraphWriter.java
@@ -73,6 +73,9 @@ public class TestCodeGraphWriter
CodeGraphModel model = new CodeGraphModel("swf", "example-module");
CodeGraphSymbol owner = new CodeGraphSymbol("as3://example/Widget",
"example.Widget", "Widget", "example", "class");
owner.setBaseType(new CodeGraphReference("as3://Object", "Object",
true, false));
+ CodeGraphMetadata metadata = new CodeGraphMetadata("DefaultProperty");
+ metadata.addAttribute(new CodeGraphMetadataAttribute(null, "content"));
+ owner.addMetadata(metadata);
CodeGraphSymbol method = new
CodeGraphSymbol("as3://example/Widget#work(String)",
"example.Widget.work", "work", "example", "method");
method.setDeclaringType(new CodeGraphReference(owner.getId(),
owner.getQualifiedName(), false, false));
@@ -92,6 +95,8 @@ public class TestCodeGraphWriter
assertTrue(firstOutput.toString().contains("\"baseType\": {"));
assertTrue(firstOutput.toString().contains("\"members\": ["));
assertTrue(firstOutput.toString().contains("\"parameters\": ["));
+ assertTrue(firstOutput.toString().contains("\"metadata\": ["));
+ assertTrue(firstOutput.toString().contains("\"key\": null"));
assertTrue(firstOutput.toString().contains("\"external\": true"));
}
}
\ No newline at end of file
diff --git a/compiler-jx/src/test/resources/codegraph/golden/GraphBase.as
b/compiler-jx/src/test/resources/codegraph/golden/GraphBase.as
index 8d89f6d31..8dbf45f4f 100644
--- a/compiler-jx/src/test/resources/codegraph/golden/GraphBase.as
+++ b/compiler-jx/src/test/resources/codegraph/golden/GraphBase.as
@@ -2,6 +2,7 @@ package codegraph.golden
{
public class GraphBase
{
+ [Bindable(event="labelChanged")]
public var label:String;
public function inheritedMethod():void
diff --git a/compiler-jx/src/test/resources/codegraph/golden/GraphRoot.as
b/compiler-jx/src/test/resources/codegraph/golden/GraphRoot.as
index 0462b0ae2..e7aadf66b 100644
--- a/compiler-jx/src/test/resources/codegraph/golden/GraphRoot.as
+++ b/compiler-jx/src/test/resources/codegraph/golden/GraphRoot.as
@@ -1,5 +1,7 @@
package codegraph.golden
{
+ [Event(name="complete", type="codegraph.golden.GraphEvent")]
+ [DefaultProperty("label")]
public class GraphRoot extends GraphBase implements IGraphContract
{
public function GraphRoot(value:String)
diff --git a/compiler-jx/src/test/resources/codegraph/golden/GraphRoot.json
b/compiler-jx/src/test/resources/codegraph/golden/GraphRoot.json
index e0ddcf438..7e6118925 100644
--- a/compiler-jx/src/test/resources/codegraph/golden/GraphRoot.json
+++ b/compiler-jx/src/test/resources/codegraph/golden/GraphRoot.json
@@ -52,7 +52,18 @@
"qualifiedName": "String",
"external": true,
"unresolved": false
- }
+ },
+ "metadata": [
+ {
+ "name": "Bindable",
+ "attributes": [
+ {
+ "key": null,
+ "value": "labelChanged"
+ }
+ ]
+ }
+ ]
}
]
},
@@ -76,6 +87,30 @@
"unresolved": false
}
],
+ "metadata": [
+ {
+ "name": "Event",
+ "attributes": [
+ {
+ "key": "name",
+ "value": "complete"
+ },
+ {
+ "key": "type",
+ "value": "codegraph.golden.GraphEvent"
+ }
+ ]
+ },
+ {
+ "name": "DefaultProperty",
+ "attributes": [
+ {
+ "key": null,
+ "value": "label"
+ }
+ ]
+ }
+ ],
"members": [
{
"id": "as3://codegraph/golden/GraphRoot#constructor(String)",