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

Reply via email to