BowlerHatLLC / vscode-as3mxml

ActionScript & MXML language extension for Visual Studio Code. Develop apps for Adobe AIR, Adobe Flash Player, or Apache Royale.
https://as3mxml.com/
Apache License 2.0
257 stars 39 forks source link

Workspace organization #384

Closed cgascons closed 5 years ago

cgascons commented 5 years ago

Hi,

I'm trying to setup my workspace but I'm finding some issues. I have read many related issues but none seem to point me in the right direction and I'm hitting a wall.

My current situation is as follows:

  1. MainEngine (contains 99% of all the code in our projects)
  2. AirLibrary (used by mobile and Steam games, contains code linked to some ANEs and AIR specific code)
  3. MobileLibrary (used by all mobile games, contains code linked to mobile-specific ANEs)
  4. SteamLibrary (used by Steam games, contains code linked to Steam-specific ANEs)
  5. BrowserLibrary (used by browser projects)

We did separate these libraries in projects when using Flash Builder because of their sdk nature.

Our current workspace on FlashBuilder was quite heavy, each library and each game platform is a project, so: 5 games x 4 platforms + 5 libraries = 25 projects.

My intention using VS was to have it all clean and tidy, my current setup is the following:

1 - I created one workspace per library so that's 5 VS projects, so far so good. 2 - I think it would be nice to have 1 workspace per game and have 4 folders inside, one per platform so something like this:

image

Inside of each of the platform folders I have their bin and src folders. On the workspace root I created one asconfig.json per platform as well as a default asconfig.json for the workspace itself. Also, the launch.json file contains all the setups for each platform, which is awesome.

My intention is to be able to debug the games and be able to access (or set breakpoints on) the source code of my libraries, so the only way that I believe I have to access it is by adding their src folders into the source-path compiler option.

I have been playing around for a while and my current setup allows me to launch/debug every platform just fine, the problem comes when I try to access any .as file of any of the previously attached sources.

I had to add this to asconfig.json in order to reach my current state:

{
    "compilerOptions": {
        "accessible": true,
        "source-path": [
                 "../TCGEngine/src",
                 "../FSMobileLibrary/src",
                 "../FSAirLibrary/src",
                 "../FSBrowserLibrary/src",
        "../TCGEngine/media",
                 "media",
        "media_on_demand",
        "media_project",
        "media_on_demand_project"
        ],
        "library-path": [
        "../TCGEngine/bin/TCGEngine.swc",
        "../FSMobileLibrary/bin/FSMobileLibrary.swc",
        "../FSAirLibrary/bin/FSAirLibrary.swc",
        "../FSBrowserLibrary/bin/FSBrowserLibrary.swc",
        "../TCGEngine/libs_browser",
        "../TCGEngine/libs",
        "../TCGEngine/anes/steam/FRESteamWorks.ane",
        "../TCGEngine/anes/common/com.distriqt.Application.ane",
        "../TCGEngine/anes/common/com.distriqt.Bolts.ane",
        "../TCGEngine/anes/common/com.distriqt.Core.ane",
        "../TCGEngine/anes/common/com.distriqt.FacebookAPI.ane",
        "../TCGEngine/anes/common/com.distriqt.Firebase.ane",
        "../TCGEngine/anes/common/com.distriqt.InAppBilling.ane",
        "../TCGEngine/anes/common/com.distriqt.Notifications.ane",
        "../TCGEngine/anes/common/com.distriqt.Share.ane",
        "../TCGEngine/anes/common/com.distriqt.Vibration.ane",
        "../TCGEngine/anes/common/com.distriqt.PushNotifications.FCM.ane",
        "../TCGEngine/anes/android/com.distriqt.androidsupport.V4.ane",
        "../TCGEngine/anes/android/com.distriqt.playservices.Auth.ane",
        "../TCGEngine/anes/android/com.distriqt.playservices.Base.ane",
        "../TCGEngine/anes/android/com.distriqt.androidsupport.AppCompatV7.ane",
        "../TCGEngine/anes/android/com.distriqt.androidsupport.CardViewV7.ane",
        "../TCGEngine/anes/android/com.distriqt.androidsupport.CustomTabs.ane",
        "../TCGEngine/anes/android/com.distriqt.ExpansionFiles.ane",
        "../TCGEngine/anes/android/com.distriqt.androidsupport.Design.ane",
        "../TCGEngine/anes/android/com.distriqt.androidsupport.RecyclerViewV7.ane"
        ],
    },
    "files": [
        "src/MainEmpty.as"
    ],
    "config": "airmobile"
}

As you can see to make this work I have also had to create a src/MainEmpty class which does simply nothing, it's empty.

I can (sometimes!) access the classes of the libraries, some other times I start getting errors (up to 30k+) and after deleting a blank space and saving the workspace they banish, not quite sure what's going on to be honest. Also, from time to time when Pressing Ctrl + T to access an actionscript source class the class itself seems to be extracted from an already compiled swc which only shows me the headers of the functions in it, quite weird.

Sample of an error:

com.google.common.util.concurrent.UncheckedExecutionException: java.lang.NullPointerException
    at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2214)
    at com.google.common.cache.LocalCache.get(LocalCache.java:4053)
    at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:4057)
    at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4986)
    at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4992)
    at org.apache.royale.compiler.internal.projects.CompilerProject.getCacheForScope(CompilerProject.java:676)
    at org.apache.royale.compiler.internal.scopes.ASScope.findPropertyQualified(ASScope.java:1592)
    at org.apache.royale.compiler.internal.definitions.references.ResolvedQualifiersReference.resolve(ResolvedQualifiersReference.java:80)
    at org.apache.royale.compiler.internal.definitions.DefinitionBase.resolveType(DefinitionBase.java:1062)
    at org.apache.royale.compiler.internal.definitions.DefinitionBase.resolveType(DefinitionBase.java:1102)
    at org.apache.royale.compiler.internal.definitions.ClassDefinition.resolveBaseClass(ClassDefinition.java:362)
    at org.apache.royale.compiler.internal.definitions.TypeDefinitionBase$TypeIterator.pushChildren(TypeDefinitionBase.java:283)
    at org.apache.royale.compiler.internal.definitions.TypeDefinitionBase$TypeIterator.next(TypeDefinitionBase.java:217)
    at org.apache.royale.compiler.internal.definitions.TypeDefinitionBase$TypeIterator.next(TypeDefinitionBase.java:175)
    at org.apache.royale.compiler.internal.scopes.TypeScope.getPropertyForMemberAccess(TypeScope.java:322)
    at org.apache.royale.compiler.internal.scopes.ScopeView.getPropertyForMemberAccess(ScopeView.java:81)
    at org.apache.royale.compiler.internal.scopes.ASScope.getPropertyFromDef(ASScope.java:903)
    at org.apache.royale.compiler.internal.scopes.ASScope.getPropertyFromDef(ASScope.java:865)
    at org.apache.royale.compiler.internal.scopes.ASScope.getPropertyFromDef(ASScope.java:784)
    at org.apache.royale.compiler.internal.tree.as.IdentifierNode.resolveMemberRef(IdentifierNode.java:924)
    at org.apache.royale.compiler.internal.tree.as.IdentifierNode.resolve(IdentifierNode.java:388)
    at org.apache.royale.compiler.internal.tree.as.MemberAccessExpressionNode.resolve(MemberAccessExpressionNode.java:124)
    at org.apache.royale.compiler.internal.semantics.SemanticUtils.transformNameToConstantValue(SemanticUtils.java:2433)
    at org.apache.royale.compiler.internal.as.codegen.ABCGeneratingReducer.isCompileTimeConstant(ABCGeneratingReducer.java:2458)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter.isCompileTimeConstant(CmcEmitter.java:89)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter$JBurgAnnotation_MemberAccessExpressionID_2.cachedCost_4411a827(CmcEmitter.java:16870)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter$JBurgAnnotation_MemberAccessExpressionID_2.getCostForRule_309c259f(CmcEmitter.java:16863)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter$JBurgAnnotation_MemberAccessExpressionID_2.getCost(CmcEmitter.java:16387)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter$JBurgAnnotation_MemberAccessExpressionID_2.getCost(CmcEmitter.java:16427)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter$JBurgAnnotation_FunctionCallID_2_n.getCostForRule_258246a0(CmcEmitter.java:13084)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter$JBurgAnnotation_FunctionCallID_2_n.getCost(CmcEmitter.java:12747)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter$JBurgAnnotation_FunctionCallID_2_n.getCost(CmcEmitter.java:12802)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter$JBurgAnnotation_FunctionCallID_2_n.getCost(CmcEmitter.java:12780)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter.getNaryCost(CmcEmitter.java:39385)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter.access$000(CmcEmitter.java:29)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter$JBurgAnnotation_BlockID_0_n.getCost(CmcEmitter.java:10495)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter$JBurgAnnotation_ElseID_1.getCostForRule_6566400(CmcEmitter.java:11691)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter$JBurgAnnotation_ElseID_1.getCost(CmcEmitter.java:11631)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter.getNaryCost(CmcEmitter.java:39385)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter.access$000(CmcEmitter.java:29)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter$JBurgAnnotation_IfStatementID_1_n.getCostForRule_37a74188(CmcEmitter.java:14281)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter$JBurgAnnotation_IfStatementID_1_n.getCost(CmcEmitter.java:14218)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter.getNaryCost(CmcEmitter.java:39385)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter.access$000(CmcEmitter.java:29)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter$JBurgAnnotation_BlockID_0_n.getCost(CmcEmitter.java:10495)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter$JBurgAnnotation_FunctionID_4.getCostForRule_2164c72(CmcEmitter.java:13441)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter$JBurgAnnotation_FunctionID_4.getRule(CmcEmitter.java:13373)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter.reduceAntecedent(CmcEmitter.java:39111)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter.reduce(CmcEmitter.java:39103)
    at org.apache.royale.compiler.internal.as.codegen.CmcEmitter.burm(CmcEmitter.java:39405)
    at org.apache.royale.compiler.internal.as.codegen.ABCGenerator.generateInstructions(ABCGenerator.java:233)
    at org.apache.royale.compiler.internal.as.codegen.ABCGenerator.generateMethodBodyForFunction(ABCGenerator.java:398)
    at org.apache.royale.compiler.internal.as.codegen.ABCGenerator.generateMethodBodyForFunction(ABCGenerator.java:352)
    at org.apache.royale.compiler.internal.as.codegen.ABCGenerator.generateFunction(ABCGenerator.java:267)
    at org.apache.royale.compiler.internal.as.codegen.ClassDirectiveProcessor.declareFunction(ClassDirectiveProcessor.java:886)
    at org.apache.royale.compiler.internal.as.codegen.DirectiveProcessor.processNode(DirectiveProcessor.java:219)
    at org.apache.royale.compiler.internal.as.codegen.DirectiveProcessor.traverse(DirectiveProcessor.java:193)
    at org.apache.royale.compiler.internal.as.codegen.GlobalDirectiveProcessor.declareClass(GlobalDirectiveProcessor.java:429)
    at org.apache.royale.compiler.internal.as.codegen.DirectiveProcessor.processNode(DirectiveProcessor.java:211)
    at org.apache.royale.compiler.internal.as.codegen.DirectiveProcessor.traverse(DirectiveProcessor.java:193)
    at org.apache.royale.compiler.internal.as.codegen.GlobalDirectiveProcessor.declarePackage(GlobalDirectiveProcessor.java:455)
    at org.apache.royale.compiler.internal.as.codegen.DirectiveProcessor.processNode(DirectiveProcessor.java:228)
    at org.apache.royale.compiler.internal.as.codegen.DirectiveProcessor.traverse(DirectiveProcessor.java:193)
    at org.apache.royale.compiler.internal.as.codegen.ABCGenerator.generate(ABCGenerator.java:124)
    at org.apache.royale.compiler.internal.units.ASCompilationUnit.handleABCBytesRequest(ASCompilationUnit.java:394)
    at org.apache.royale.compiler.internal.units.CompilationUnitBase.processABCBytesRequest(CompilationUnitBase.java:875)
    at org.apache.royale.compiler.internal.units.CompilationUnitBase.access$300(CompilationUnitBase.java:108)
    at org.apache.royale.compiler.internal.units.CompilationUnitBase$4$1.call(CompilationUnitBase.java:312)
    at org.apache.royale.compiler.internal.units.CompilationUnitBase$4$1.call(CompilationUnitBase.java:308)
    at org.apache.royale.compiler.internal.units.requests.RequestMaker$1.call(RequestMaker.java:228)
    at org.apache.royale.compiler.internal.units.requests.RequestMaker$1.call(RequestMaker.java:222)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy.rejectedExecution(ThreadPoolExecutor.java:2022)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
    at org.apache.royale.compiler.internal.units.requests.RequestMaker.getRequest(RequestMaker.java:188)
    at org.apache.royale.compiler.internal.units.CompilationUnitBase.getABCBytesRequest(CompilationUnitBase.java:623)
    at org.apache.royale.compiler.internal.units.ASCompilationUnit.handleOutgoingDependenciesRequest(ASCompilationUnit.java:476)
    at org.apache.royale.compiler.internal.units.CompilationUnitBase.processOutgoingDependenciesRequest(CompilationUnitBase.java:891)
    at org.apache.royale.compiler.internal.units.CompilationUnitBase.access$500(CompilationUnitBase.java:108)
    at org.apache.royale.compiler.internal.units.CompilationUnitBase$6$1.call(CompilationUnitBase.java:387)
    at org.apache.royale.compiler.internal.units.CompilationUnitBase$6$1.call(CompilationUnitBase.java:383)
    at org.apache.royale.compiler.internal.units.requests.RequestMaker$1.call(RequestMaker.java:228)
    at org.apache.royale.compiler.internal.units.requests.RequestMaker$1.call(RequestMaker.java:222)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
    at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:770)
    at com.google.common.cache.LocalCache.get(LocalCache.java:4052)
    at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:4057)
    at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4986)
    at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4992)
    at org.apache.royale.compiler.internal.scopes.ASProjectScope.addScopeToCompilationUnitScopeList(ASProjectScope.java:1310)
    at org.apache.royale.compiler.internal.projects.CompilerProject$ScopeCacheLoader.load(CompilerProject.java:107)
    at org.apache.royale.compiler.internal.projects.CompilerProject$ScopeCacheLoader.load(CompilerProject.java:96)
    at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3628)
    at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2336)
    at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2295)
    at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2208)
    ... 88 more

Any ideas of what could I do to make this work? I don't care if I have to separate each platform into a separate VS project, I tried it already but still found the same errors though.

Any help will be appreciated.

joshtynjala commented 5 years ago

With a complex project structure like that, it's likely that you are running into some known issues in version 0.9.4 of the Apache Royale compiler. This is the current version included with the VSCode extension to power the code intelligence (even for projects that use other SDKs).

The issues have been fixed in the upcoming version 0.9.6 of Royale. I plan to include this update as soon as it is released. However, you can start using it today by downloading the SDK and changing a setting in VSCode, of you'd like.

Go here: https://royale.apache.org/download/

Find the "JSOnly Nightly Build" near the bottom of the page. Download apache-royale-0.9.6-bin-js.zip on Windows or apache-royale-0.9.6-bin-js.tar.gz on macOS, and extract it somewhere.

In VSCode, set the as3mxml.sdk.editor setting to the royale-asjs folder inside the unzipped SDK. Note that this is different from the as3mxml.sdk.framework setting that you use to point to your project's SDK.

jnpatrick99 commented 5 years ago

... Find the "JSOnly Nightly Build" near the bottom of the page. Download apache-royale-0.9.6-bin-js.zip on Windows or apache-royale-0.9.6-bin-js.tar.gz on macOS, and extract it somewhere. ...

Wow! This finally solved all my 1000s of Problems and Royale's NullPointerExceptions connected to unknown compiler defines (https://github.com/BowlerHatLLC/vscode-as3mxml/issues/370). Thanks again for all your hard work!

joshtynjala commented 5 years ago

@jnpatrick99 Great news! I think the null pointer exceptions with unknown defines is a bug that I just fixed in the compiler this morning. 😎

cgascons commented 5 years ago

@joshtynjala This is so far looking promising indeed, I just downloaded the new package and seems to be working fine! I will let you know if I run into more related issues. Thanks!

cgascons commented 5 years ago

Hey @joshtynjala, sorry to re-open this. I've actually got a question regarding the workspace organization, please let me know if you need me to open a new issue for this and I will do it.

Is there a way to force using a specific asconfig.json file to attach a swf to a mobile device for debugging?

I'm using the stated configuration above, and I'm having a hard time trying to debug on an android device my project. Creating a release and attaching it manually to device works fine, as well as debugging on simulator, but when I select the "Install and Attach (Android)" debug task I get an error that says:

Preparing to install Adobe AIR application...
Failed to debug SWF. Error reading application <id> in application descriptor for platform "android".

This error goes away when in the root asconfig.json file (the one I also pasted above) I set the application attribute to: _android/src/MainGame-app.xml. Which has already been set in asconfig-android.json but seems to be ignoring.

Any advice?

This is the launch.json task that I believe is not working properly:

{
            "type": "swf",
            "request": "attach",
            "name": "Install and Attach (Android)",
            "platform": "android",
            "connect": true
}

Thanks beforehand!

joshtynjala commented 5 years ago

There's not currently a way to tell it to use a different asconfig file for launch. It will only use the main asconfig.json. I created #386 to make this more configurable.

cgascons commented 5 years ago

Thank you Josh, we will wait for it, I do believe it will help us.