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 58f92e591 Enhance CODEGRAPH functionality and add tests for error
handling and output generation
58f92e591 is described below
commit 58f92e5911839a492083e01b825858234fbbd3b6
Author: Harbs <[email protected]>
AuthorDate: Fri Jul 31 14:16:30 2026 +0300
Enhance CODEGRAPH functionality and add tests for error handling and output
generation
---
.../apache/royale/compiler/clients/CODEGRAPH.java | 36 ++++
.../internal/codegen/graph/CodeGraphExporter.java | 6 +-
.../royale/compiler/clients/TestCODEGRAPH.java | 119 +++++++++++
.../codegen/graph/TestCodeGraphExporter.java | 2 +-
.../test/resources/codegraph/InvalidCodeGraph.as | 10 +
.../test/resources/codegraph/golden/GraphBase.as | 11 +
.../test/resources/codegraph/golden/GraphRoot.as | 18 ++
.../test/resources/codegraph/golden/GraphRoot.json | 224 +++++++++++++++++++++
.../resources/codegraph/golden/IGraphContract.as | 7 +
9 files changed, 430 insertions(+), 3 deletions(-)
diff --git
a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/CODEGRAPH.java
b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/CODEGRAPH.java
index 662d2891b..0acd3c0c3 100644
---
a/compiler-jx/src/main/java/org/apache/royale/compiler/clients/CODEGRAPH.java
+++
b/compiler-jx/src/main/java/org/apache/royale/compiler/clients/CODEGRAPH.java
@@ -85,6 +85,14 @@ public class CODEGRAPH extends MXMLJSCRoyale
buildArtifact();
if (jsTarget == null)
return false;
+ if (!config.getCreateTargetWithErrors())
+ {
+ Collection<ICompilerProblem> errors = new
ArrayList<ICompilerProblem>();
+ Collection<ICompilerProblem> warnings = new
ArrayList<ICompilerProblem>();
+ problems.getErrorsAndWarnings(errors, warnings);
+ if (!errors.isEmpty())
+ return false;
+ }
Collection<IDefinition> definitions = new ArrayList<IDefinition>();
for (ICompilationUnit compilationUnit :
getReachableCompilationUnits())
@@ -123,10 +131,14 @@ public class CODEGRAPH extends MXMLJSCRoyale
Collection<ICompilationUnit> result = new
ArrayList<ICompilationUnit>();
for (ICompilationUnit compilationUnit : reachableCompilationUnits)
{
+ if (compilationUnit.isInvisible())
+ continue;
ICompilationUnit.UnitType unitType =
compilationUnit.getCompilationUnitType();
if (unitType != ICompilationUnit.UnitType.AS_UNIT
&& unitType != ICompilationUnit.UnitType.MXML_UNIT)
continue;
+ if (!isProjectSource(compilationUnit))
+ continue;
if (externs.contains(compilationUnit.getQualifiedNames().get(0)))
continue;
if (project.isExternalLinkage(compilationUnit))
@@ -136,6 +148,21 @@ public class CODEGRAPH extends MXMLJSCRoyale
return result;
}
+ private boolean isProjectSource(ICompilationUnit compilationUnit)
+ {
+ File sourceFile = new
File(compilationUnit.getAbsoluteFilename()).getAbsoluteFile();
+ if (project.isFileOnSourcePath(sourceFile))
+ return true;
+ if (sourceFile.equals(new
File(config.getTargetFile()).getAbsoluteFile()))
+ return true;
+ for (String includeSource : config.getIncludeSources())
+ {
+ if (sourceFile.equals(new File(includeSource).getAbsoluteFile()))
+ return true;
+ }
+ return false;
+ }
+
@Override
protected boolean setupTargetFile() throws InterruptedException
{
@@ -150,7 +177,16 @@ public class CODEGRAPH extends MXMLJSCRoyale
private ITargetSettings getCodeGraphTargetSettings()
{
if (targetSettings == null)
+ {
+ Collection<File> includeSources = new ArrayList<File>();
+ for (String includeSource : config.getIncludeSources())
+ includeSources.add(new File(includeSource));
+ File targetFile = new File(config.getTargetFile());
+ if (!includeSources.contains(targetFile))
+ includeSources.add(targetFile);
+ projectConfigurator.setIncludeSources(includeSources);
targetSettings =
projectConfigurator.getTargetSettings(getTargetType());
+ }
if (targetSettings == null)
problems.addAll(projectConfigurator.getConfigurationProblems());
return targetSettings;
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 b987ad54a..a8968197d 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
@@ -19,9 +19,11 @@
package org.apache.royale.compiler.internal.codegen.graph;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -103,7 +105,7 @@ public final class CodeGraphExporter
{
boolean isConstructor = memberDefinition instanceof
IFunctionDefinition
&& ((IFunctionDefinition)memberDefinition).isConstructor();
- if (!memberDefinition.isPublic() ||
memberDefinition.isImplicit() || isConstructor)
+ if (!memberDefinition.isPublic() || memberDefinition.isImplicit()
|| isConstructor)
continue;
if (memberDefinition instanceof IFunctionDefinition)
symbol.addMember(exportFunction((IFunctionDefinition)memberDefinition,
definition));
@@ -162,7 +164,7 @@ public final class CodeGraphExporter
private String createCallableId(IFunctionDefinition definition,
ITypeDefinition declaringType)
{
- java.util.List<String> parameterTypes = new
java.util.ArrayList<String>();
+ List<String> parameterTypes = new ArrayList<String>();
for (IParameterDefinition parameterDefinition :
definition.getParameters())
{
ITypeDefinition parameterType =
parameterDefinition.resolveType(project);
diff --git
a/compiler-jx/src/test/java/org/apache/royale/compiler/clients/TestCODEGRAPH.java
b/compiler-jx/src/test/java/org/apache/royale/compiler/clients/TestCODEGRAPH.java
new file mode 100644
index 000000000..c6873fa50
--- /dev/null
+++
b/compiler-jx/src/test/java/org/apache/royale/compiler/clients/TestCODEGRAPH.java
@@ -0,0 +1,119 @@
+/*
+ *
+ * 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.clients;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.royale.compiler.problems.ICompilerProblem;
+import org.apache.royale.utils.ITestAdapter;
+import org.apache.royale.utils.TestAdapterFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCODEGRAPH
+{
+ private final ITestAdapter testAdapter =
TestAdapterFactory.getTestAdapter();
+ private File outputFile;
+ private List<ICompilerProblem> problems;
+
+ @Before
+ public void setUp()
+ {
+ outputFile = new File(testAdapter.getTempDir(),
"codegraph/InvalidCodeGraph.json");
+ FileUtils.deleteQuietly(outputFile);
+ }
+
+ @After
+ public void tearDown()
+ {
+ FileUtils.deleteQuietly(outputFile);
+ }
+
+ @Test
+ public void testCompilerErrorsPreventOutputByDefault()
+ {
+ int exitCode = compile(false);
+
+ assertEquals(2, exitCode);
+ assertFalse(outputFile.exists());
+ }
+
+ @Test
+ public void testCreateTargetWithErrorsAllowsOutput()
+ {
+ int exitCode = compile(true);
+
+ assertEquals(2, exitCode);
+ assertTrue(problems.toString(), outputFile.exists());
+ }
+
+ @Test
+ public void testCompilerBackedGraphIsDeterministic() throws IOException
+ {
+ File sourceDirectory = testAdapter.getUnitTestBaseDir();
+ File sourceFile = new File(sourceDirectory,
"codegraph/golden/GraphRoot.as");
+ outputFile = new File(testAdapter.getTempDir(),
"codegraph/GraphRoot.json");
+
+ int firstExitCode = compile(sourceFile, sourceDirectory, false);
+ assertEquals(problems.toString(), 0, firstExitCode);
+ String firstOutput = FileUtils.readFileToString(outputFile, "UTF-8");
+
+ int secondExitCode = compile(sourceFile, sourceDirectory, false);
+ assertEquals(problems.toString(), 0, secondExitCode);
+ String secondOutput = FileUtils.readFileToString(outputFile, "UTF-8");
+
+ assertEquals(firstOutput, secondOutput);
+ File goldenFile = new File(sourceDirectory,
"codegraph/golden/GraphRoot.json");
+ String goldenOutput = FileUtils.readFileToString(goldenFile, "UTF-8");
+ assertEquals(goldenOutput, firstOutput);
+ }
+
+ private int compile(boolean createTargetWithErrors)
+ {
+ File sourceFile = new File(testAdapter.getUnitTestBaseDir(),
"codegraph/InvalidCodeGraph.as");
+ return compile(sourceFile, null, createTargetWithErrors);
+ }
+
+ private int compile(File sourceFile, File sourceDirectory, boolean
createTargetWithErrors)
+ {
+ File jsSWC = new File("../compiler-externc/target/js.swc");
+ List<String> arguments = new ArrayList<String>();
+ arguments.add("-external-library-path=" + jsSWC.getPath());
+ arguments.add("-output=" + outputFile.getPath());
+ arguments.add("-include-sources=" + sourceFile.getPath());
+ if (sourceDirectory != null)
+ arguments.add("-source-path=" + sourceDirectory.getPath());
+ if (createTargetWithErrors)
+ arguments.add("-create-target-with-errors=true");
+ arguments.add(sourceFile.getPath());
+
+ problems = new ArrayList<ICompilerProblem>();
+ return new CODEGRAPH().mainNoExit(arguments.toArray(new
String[arguments.size()]), problems, false);
+ }
+}
\ No newline at end of file
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 15d4b0084..fffd523b4 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
@@ -106,6 +106,6 @@ public class TestCodeGraphExporter extends ASTestBase
if (kind.equals(member.getKind()))
return member;
}
- return null;
+ throw new AssertionError("Expected " + kind + " member in " +
owner.getId());
}
}
\ No newline at end of file
diff --git a/compiler-jx/src/test/resources/codegraph/InvalidCodeGraph.as
b/compiler-jx/src/test/resources/codegraph/InvalidCodeGraph.as
new file mode 100644
index 000000000..2d35835c1
--- /dev/null
+++ b/compiler-jx/src/test/resources/codegraph/InvalidCodeGraph.as
@@ -0,0 +1,10 @@
+package codegraph
+{
+ public class InvalidCodeGraph
+ {
+ public function broken():void
+ {
+ missingName;
+ }
+ }
+}
\ 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
new file mode 100644
index 000000000..8d89f6d31
--- /dev/null
+++ b/compiler-jx/src/test/resources/codegraph/golden/GraphBase.as
@@ -0,0 +1,11 @@
+package codegraph.golden
+{
+ public class GraphBase
+ {
+ public var label:String;
+
+ public function inheritedMethod():void
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/compiler-jx/src/test/resources/codegraph/golden/GraphRoot.as
b/compiler-jx/src/test/resources/codegraph/golden/GraphRoot.as
new file mode 100644
index 000000000..0462b0ae2
--- /dev/null
+++ b/compiler-jx/src/test/resources/codegraph/golden/GraphRoot.as
@@ -0,0 +1,18 @@
+package codegraph.golden
+{
+ public class GraphRoot extends GraphBase implements IGraphContract
+ {
+ public function GraphRoot(value:String)
+ {
+ }
+
+ public function execute(required:String, optional:Number = 2,
...rest):Boolean
+ {
+ return true;
+ }
+
+ private function hidden():void
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/compiler-jx/src/test/resources/codegraph/golden/GraphRoot.json
b/compiler-jx/src/test/resources/codegraph/golden/GraphRoot.json
new file mode 100644
index 000000000..e0ddcf438
--- /dev/null
+++ b/compiler-jx/src/test/resources/codegraph/golden/GraphRoot.json
@@ -0,0 +1,224 @@
+{
+ "schemaVersion": "1.0",
+ "target": "js",
+ "module": null,
+ "symbols": [
+ {
+ "id": "as3://codegraph/golden/GraphBase",
+ "qualifiedName": "codegraph.golden.GraphBase",
+ "baseName": "GraphBase",
+ "package": "codegraph.golden",
+ "kind": "class",
+ "baseType": {
+ "id": "as3://Object",
+ "qualifiedName": "Object",
+ "external": true,
+ "unresolved": false
+ },
+ "members": [
+ {
+ "id": "as3://codegraph/golden/GraphBase#inheritedMethod()",
+ "qualifiedName": "inheritedMethod",
+ "baseName": "inheritedMethod",
+ "package": "codegraph.golden",
+ "kind": "method",
+ "declaringType": {
+ "id": "as3://codegraph/golden/GraphBase",
+ "qualifiedName": "codegraph.golden.GraphBase",
+ "external": false,
+ "unresolved": false
+ },
+ "returnType": {
+ "id": "as3://void",
+ "qualifiedName": "void",
+ "external": true,
+ "unresolved": false
+ }
+ },
+ {
+ "id": "as3://codegraph/golden/GraphBase#label",
+ "qualifiedName": "label",
+ "baseName": "label",
+ "package": "codegraph.golden",
+ "kind": "field",
+ "declaringType": {
+ "id": "as3://codegraph/golden/GraphBase",
+ "qualifiedName": "codegraph.golden.GraphBase",
+ "external": false,
+ "unresolved": false
+ },
+ "type": {
+ "id": "as3://String",
+ "qualifiedName": "String",
+ "external": true,
+ "unresolved": false
+ }
+ }
+ ]
+ },
+ {
+ "id": "as3://codegraph/golden/GraphRoot",
+ "qualifiedName": "codegraph.golden.GraphRoot",
+ "baseName": "GraphRoot",
+ "package": "codegraph.golden",
+ "kind": "class",
+ "baseType": {
+ "id": "as3://codegraph/golden/GraphBase",
+ "qualifiedName": "codegraph.golden.GraphBase",
+ "external": false,
+ "unresolved": false
+ },
+ "interfaces": [
+ {
+ "id": "as3://codegraph/golden/IGraphContract",
+ "qualifiedName": "codegraph.golden.IGraphContract",
+ "external": false,
+ "unresolved": false
+ }
+ ],
+ "members": [
+ {
+ "id": "as3://codegraph/golden/GraphRoot#constructor(String)",
+ "qualifiedName": "codegraph.golden.GraphRoot",
+ "baseName": "GraphRoot",
+ "package": "codegraph.golden",
+ "kind": "constructor",
+ "declaringType": {
+ "id": "as3://codegraph/golden/GraphRoot",
+ "qualifiedName": "codegraph.golden.GraphRoot",
+ "external": false,
+ "unresolved": false
+ },
+ "parameters": [
+ {
+ "name": "value",
+ "type": {
+ "id": "as3://String",
+ "qualifiedName": "String",
+ "external": true,
+ "unresolved": false
+ },
+ "optional": false,
+ "rest": false,
+ "defaultValue": null
+ }
+ ]
+ },
+ {
+ "id":
"as3://codegraph/golden/GraphRoot#execute(String,Number,Array)",
+ "qualifiedName": "execute",
+ "baseName": "execute",
+ "package": "codegraph.golden",
+ "kind": "method",
+ "declaringType": {
+ "id": "as3://codegraph/golden/GraphRoot",
+ "qualifiedName": "codegraph.golden.GraphRoot",
+ "external": false,
+ "unresolved": false
+ },
+ "returnType": {
+ "id": "as3://Boolean",
+ "qualifiedName": "Boolean",
+ "external": true,
+ "unresolved": false
+ },
+ "parameters": [
+ {
+ "name": "required",
+ "type": {
+ "id": "as3://String",
+ "qualifiedName": "String",
+ "external": true,
+ "unresolved": false
+ },
+ "optional": false,
+ "rest": false,
+ "defaultValue": null
+ },
+ {
+ "name": "optional",
+ "type": {
+ "id": "as3://Number",
+ "qualifiedName": "Number",
+ "external": true,
+ "unresolved": false
+ },
+ "optional": true,
+ "rest": false,
+ "defaultValue": 2
+ },
+ {
+ "name": "rest",
+ "type": {
+ "id": "as3://Array",
+ "qualifiedName": "Array",
+ "external": true,
+ "unresolved": false
+ },
+ "optional": false,
+ "rest": true,
+ "defaultValue": null
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": "as3://codegraph/golden/IGraphContract",
+ "qualifiedName": "codegraph.golden.IGraphContract",
+ "baseName": "IGraphContract",
+ "package": "codegraph.golden",
+ "kind": "interface"
+ }
+ ],
+ "externalSymbols": [
+ {
+ "id": "as3://Array",
+ "qualifiedName": "Array",
+ "baseName": "Array",
+ "package": "",
+ "kind": "class",
+ "external": true
+ },
+ {
+ "id": "as3://Boolean",
+ "qualifiedName": "Boolean",
+ "baseName": "Boolean",
+ "package": "",
+ "kind": "class",
+ "external": true
+ },
+ {
+ "id": "as3://Number",
+ "qualifiedName": "Number",
+ "baseName": "Number",
+ "package": "",
+ "kind": "class",
+ "external": true
+ },
+ {
+ "id": "as3://Object",
+ "qualifiedName": "Object",
+ "baseName": "Object",
+ "package": "",
+ "kind": "class",
+ "external": true
+ },
+ {
+ "id": "as3://String",
+ "qualifiedName": "String",
+ "baseName": "String",
+ "package": "",
+ "kind": "class",
+ "external": true
+ },
+ {
+ "id": "as3://void",
+ "qualifiedName": "void",
+ "baseName": "void",
+ "package": "",
+ "kind": "class",
+ "external": true
+ }
+ ]
+}
diff --git a/compiler-jx/src/test/resources/codegraph/golden/IGraphContract.as
b/compiler-jx/src/test/resources/codegraph/golden/IGraphContract.as
new file mode 100644
index 000000000..3c49ced49
--- /dev/null
+++ b/compiler-jx/src/test/resources/codegraph/golden/IGraphContract.as
@@ -0,0 +1,7 @@
+package codegraph.golden
+{
+ public interface IGraphContract
+ {
+ function execute(required:String, optional:Number = 2,
...rest):Boolean;
+ }
+}
\ No newline at end of file