├── .github
└── workflows
│ ├── Build.yml
│ └── WinBuild.yml
├── .gitignore
├── .gitmodules
├── .idea
├── encodings.xml
├── misc.xml
└── vcs.xml
├── .scalafmt.conf
├── LICENSE
├── README.md
├── apexlink.iml
├── apexlink
├── .gitignore
├── .idea
│ ├── .gitignore
│ ├── .idea
│ │ ├── .idea.iml
│ │ ├── encodings.xml
│ │ ├── misc.xml
│ │ ├── modules.xml
│ │ └── workspace.xml
│ ├── ApexLink.iml
│ ├── codeStyles
│ │ ├── Project.xml
│ │ └── codeStyleConfig.xml
│ ├── compiler.xml
│ ├── copyright
│ │ └── profiles_settings.xml
│ ├── dictionaries
│ │ └── kevin.xml
│ ├── encodings.xml
│ ├── jarRepositories.xml
│ ├── libraries
│ │ ├── Maven__com_github_nawforce_scala_json_rpc_2_13_1_0_1.xml
│ │ ├── Maven__com_github_nawforce_scala_json_rpc_upickle_json_serializer_2_13_1_0_1.xml
│ │ ├── Maven__com_google_guava_guava_18_0.xml
│ │ ├── Maven__com_google_jimfs_jimfs_1_1.xml
│ │ ├── Maven__com_lihaoyi_geny_2_13_0_6_2.xml
│ │ ├── Maven__com_lihaoyi_ujson_2_13_1_2_0.xml
│ │ ├── Maven__com_lihaoyi_upack_2_13_1_2_0.xml
│ │ ├── Maven__com_lihaoyi_upickle_2_13_1_2_0.xml
│ │ ├── Maven__com_lihaoyi_upickle_core_2_13_1_2_0.xml
│ │ ├── Maven__com_lihaoyi_upickle_implicits_2_13_1_2_0.xml
│ │ ├── Maven__org_antlr_antlr4_runtime_4_8_1.xml
│ │ ├── Maven__org_scala_js_scalajs_stubs_2_13_1_0_0.xml
│ │ ├── Maven__org_scala_lang_modules_scala_collection_compat_2_13_2_1_4.xml
│ │ ├── Maven__org_scala_lang_modules_scala_parallel_collections_2_13_1_0_0.xml
│ │ ├── Maven__org_scala_lang_modules_scala_xml_2_13_1_3_0.xml
│ │ ├── Maven__org_scala_lang_scala_library_2_13_3.xml
│ │ ├── Maven__org_scala_lang_scala_reflect_2_13_3.xml
│ │ ├── Maven__org_scalactic_scalactic_2_13_3_2_2.xml
│ │ ├── Maven__org_scalatest_scalatest_2_13_3_2_2.xml
│ │ ├── Maven__org_scalatest_scalatest_compatible_3_2_2.xml
│ │ ├── Maven__org_scalatest_scalatest_core_2_13_3_2_2.xml
│ │ ├── Maven__org_scalatest_scalatest_diagrams_2_13_3_2_2.xml
│ │ ├── Maven__org_scalatest_scalatest_featurespec_2_13_3_2_2.xml
│ │ ├── Maven__org_scalatest_scalatest_flatspec_2_13_3_2_2.xml
│ │ ├── Maven__org_scalatest_scalatest_freespec_2_13_3_2_2.xml
│ │ ├── Maven__org_scalatest_scalatest_funspec_2_13_3_2_2.xml
│ │ ├── Maven__org_scalatest_scalatest_funsuite_2_13_3_2_2.xml
│ │ ├── Maven__org_scalatest_scalatest_matchers_core_2_13_3_2_2.xml
│ │ ├── Maven__org_scalatest_scalatest_mustmatchers_2_13_3_2_2.xml
│ │ ├── Maven__org_scalatest_scalatest_propspec_2_13_3_2_2.xml
│ │ ├── Maven__org_scalatest_scalatest_refspec_2_13_3_2_2.xml
│ │ ├── Maven__org_scalatest_scalatest_shouldmatchers_2_13_3_2_2.xml
│ │ └── Maven__org_scalatest_scalatest_wordspec_2_13_3_2_2.xml
│ ├── misc.xml
│ ├── modules.xml
│ ├── runConfigurations.xml
│ ├── scala_compiler.xml
│ ├── uiDesigner.xml
│ └── vcs.xml
├── .scalafmt.conf
├── doc
│ └── Types.md
├── images
│ ├── FindZombies.png
│ └── UnusedField.png
├── pom.xml
└── src
│ ├── META-INF
│ └── MANIFEST.MF
│ ├── main
│ ├── java
│ │ └── com
│ │ │ ├── nawforce
│ │ │ └── apexlink
│ │ │ │ └── api
│ │ │ │ └── IssuesCollection.java
│ │ │ └── vmware
│ │ │ └── antlr4c3
│ │ │ └── CodeCompletionCore.java
│ └── scala
│ │ └── com
│ │ └── nawforce
│ │ └── apexlink
│ │ ├── ApexLink.scala
│ │ ├── api
│ │ ├── Org.scala
│ │ ├── Package.scala
│ │ ├── ServerOps.scala
│ │ └── Summary.scala
│ │ ├── cmds
│ │ ├── Check.scala
│ │ └── Server.scala
│ │ ├── cst
│ │ ├── AssignableSupport.scala
│ │ ├── BodyDeclarations.scala
│ │ ├── CST.scala
│ │ ├── Creator.scala
│ │ ├── Expressions.scala
│ │ ├── Literals.scala
│ │ ├── MethodMap.scala
│ │ ├── Operations.scala
│ │ ├── Primaries.scala
│ │ ├── Properties.scala
│ │ ├── Statements.scala
│ │ ├── TypeDeclarations.scala
│ │ ├── TypeReference.scala
│ │ ├── Variables.scala
│ │ ├── VerifyContext.scala
│ │ └── stmts
│ │ │ └── Switch.scala
│ │ ├── deps
│ │ ├── DownWalker.scala
│ │ └── TransitiveCollector.scala
│ │ ├── diagnostics
│ │ └── IssueOps.scala
│ │ ├── finding
│ │ ├── RelativeTypeName.scala
│ │ ├── TypeError.scala
│ │ ├── TypeFinder.scala
│ │ └── TypeResolver.scala
│ │ ├── memory
│ │ ├── Monitor.scala
│ │ ├── SkinnySet.scala
│ │ └── SkinnyWeakSet.scala
│ │ ├── names
│ │ ├── TypeIdentifiers.scala
│ │ ├── TypeNames.scala
│ │ └── XNames.scala
│ │ ├── org
│ │ ├── CompletionProvider.scala
│ │ ├── DefinitionProvider.scala
│ │ ├── Flusher.scala
│ │ ├── IssuesManager.scala
│ │ ├── Module.scala
│ │ ├── ModuleCompletions.scala
│ │ ├── OrgImpl.scala
│ │ ├── PackageAPI.scala
│ │ ├── PackageImpl.scala
│ │ ├── SObjectDeployer.scala
│ │ ├── StreamDeployer.scala
│ │ ├── TextOps.scala
│ │ └── package.scala
│ │ ├── plugins
│ │ ├── Plugin.scala
│ │ ├── PluginDispatcher.scala
│ │ ├── PluginsManager.scala
│ │ └── UnusedPlugin.scala
│ │ ├── rpc
│ │ ├── CompletionItemLink.scala
│ │ ├── DependencyGraph.scala
│ │ ├── LocationLink.scala
│ │ ├── OrgAPI.scala
│ │ ├── OrgAPIImpl.scala
│ │ └── RPCServer.scala
│ │ └── types
│ │ ├── apex
│ │ ├── ApexDeclaration.scala
│ │ ├── FullDeclaration.scala
│ │ ├── SummaryDeclaration.scala
│ │ ├── TriggerDeclaration.scala
│ │ └── package.scala
│ │ ├── core
│ │ ├── BasicTypeDeclaration.scala
│ │ ├── Dependent.scala
│ │ ├── DependentType.scala
│ │ ├── TypeDeclaration.scala
│ │ └── TypeId.scala
│ │ ├── other
│ │ ├── AnyDeclaration.scala
│ │ ├── ComponentDeclaration.scala
│ │ ├── InterviewDeclaration.scala
│ │ ├── LabelDeclaration.scala
│ │ ├── PageDeclaration.scala
│ │ └── VFContainer.scala
│ │ ├── platform
│ │ ├── GenericPlatformTypeDeclaration.scala
│ │ ├── PlatformModifiers.scala
│ │ ├── PlatformTypeDeclaration.scala
│ │ └── PlatformTypes.scala
│ │ ├── schema
│ │ ├── GhostSObjectDeclaration.scala
│ │ ├── SObjectDeclaration.scala
│ │ ├── SObjectFieldFinder.scala
│ │ ├── SObjectMethods.scala
│ │ └── SchemaSObjectType.scala
│ │ └── synthetic
│ │ ├── CustomFieldDeclaration.scala
│ │ └── CustomMethodDeclaration.scala
│ └── test
│ └── scala
│ └── com
│ └── nawforce
│ └── apexlink
│ ├── FileSystemHelper.scala
│ ├── TestHelper.scala
│ ├── cst
│ ├── ArrayTest.scala
│ ├── AssignTest.scala
│ ├── ClassModifierTest.scala
│ ├── ConstructorTest.scala
│ ├── CreationTest.scala
│ ├── DependencyTest.scala
│ ├── EnumModifierTest.scala
│ ├── ExtendsTest.scala
│ ├── FieldTest.scala
│ ├── IdDependencyTest.scala
│ ├── IfTest.scala
│ ├── ImplementsTest.scala
│ ├── InnerInnerTypeTest.scala
│ ├── InterfaceModifierTest.scala
│ ├── MethodShadowTest.scala
│ ├── MethodTest.scala
│ ├── OperationsTest.scala
│ ├── PropertyTest.scala
│ ├── SafeNavigationTest.scala
│ ├── SummaryTest.scala
│ ├── SuppressWarningsTest.scala
│ ├── SwitchTest.scala
│ ├── VarTest.scala
│ └── VariablesTest.scala
│ ├── finding
│ └── TypeFindingTest.scala
│ ├── org
│ └── IssueManagerTest.scala
│ ├── parsers
│ ├── CodeParserTest.scala
│ └── LiteralTokenTest.scala
│ ├── pkg
│ ├── BugTest.scala
│ ├── CachedTest.scala
│ ├── CompletionProviderTest.scala
│ ├── DefinitionProviderTest.scala
│ ├── DeleteTest.scala
│ ├── DependencyGraphTest.scala
│ ├── DependentProjectTest.scala
│ ├── GhostPackageTest.scala
│ ├── PackageAPITest.scala
│ ├── RefreshSObjectTest.scala
│ ├── RefreshTest.scala
│ └── UnusedTest.scala
│ ├── rpc
│ └── OrgAPITest.scala
│ ├── stress
│ ├── PartialStressTest.scala
│ └── RefreshStressTest.scala
│ └── types
│ ├── AmbiguousObjectTest.scala
│ ├── ComponentTest.scala
│ ├── CustomObjectTest.scala
│ ├── InterviewTest.scala
│ ├── LabelTest.scala
│ ├── LiteralTypeTest.scala
│ ├── PageTest.scala
│ ├── PlatformEventTest.scala
│ ├── PlatformTypeDeclarationTest.scala
│ ├── PlatformTypesValidationTest.scala
│ ├── SchemaManagerTest.scala
│ ├── StandardObjectTest.scala
│ ├── TriggerTest.scala
│ └── TypeStoreTest.scala
├── pkgforce
├── .gitignore
├── .scalafmt.conf
├── README.md
├── build.sbt
├── js
│ ├── npm
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── .vscode
│ │ │ └── launch.json
│ │ ├── jestconfig.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── __tests__
│ │ │ │ └── WorkspaceTest.ts
│ │ │ └── pkgforce.d.ts
│ │ └── tsconfig.json
│ └── src
│ │ ├── main
│ │ └── scala
│ │ │ └── com
│ │ │ └── nawforce
│ │ │ ├── apexparser
│ │ │ ├── ApexLexer.scala
│ │ │ ├── ApexParser.scala
│ │ │ └── CaseInsensitiveInputStream.scala
│ │ │ ├── pkgforce
│ │ │ └── api
│ │ │ │ ├── Issue.scala
│ │ │ │ ├── IssueLocation.scala
│ │ │ │ └── Workspaces.scala
│ │ │ └── runtime
│ │ │ ├── package.scala
│ │ │ ├── parsers
│ │ │ ├── CodeParser.scala
│ │ │ ├── CollectingErrorListener.scala
│ │ │ ├── PageParser.scala
│ │ │ ├── Source.scala
│ │ │ ├── SourceData.scala
│ │ │ ├── TreeVisitor.scala
│ │ │ ├── VFLexer.scala
│ │ │ ├── VFParser.scala
│ │ │ └── antlr
│ │ │ │ ├── ANTLRInputStream.scala
│ │ │ │ ├── AbstractParseTreeVisitor.scala
│ │ │ │ ├── ApexParserVisitor.scala
│ │ │ │ ├── BufferedTokenStream.scala
│ │ │ │ ├── CharStream.scala
│ │ │ │ ├── CommonTokenStream.scala
│ │ │ │ ├── ErrorNode.scala
│ │ │ │ ├── Interval.scala
│ │ │ │ ├── ParseTree.scala
│ │ │ │ ├── ParserRuleContext.scala
│ │ │ │ ├── RuleContext.scala
│ │ │ │ ├── RuleNode.scala
│ │ │ │ ├── TerminalNode.scala
│ │ │ │ └── Token.scala
│ │ │ ├── platform
│ │ │ ├── Environment.scala
│ │ │ └── Path.scala
│ │ │ └── xml
│ │ │ ├── XMLDocument.scala
│ │ │ └── XMLDom.scala
│ │ └── test
│ │ └── scala
│ │ └── com
│ │ └── nawforce
│ │ └── runtime
│ │ ├── FileSystemHelper.scala
│ │ └── imports
│ │ ├── FSMonkey.scala
│ │ └── Memfs.scala
├── jvm
│ └── src
│ │ ├── META-INF
│ │ └── MANIFEST.MF
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── nawforce
│ │ │ │ ├── pkgforce
│ │ │ │ └── api
│ │ │ │ │ ├── Issue.java
│ │ │ │ │ └── IssueLocation.java
│ │ │ │ └── runtime
│ │ │ │ └── parsers
│ │ │ │ ├── VFLexer.java
│ │ │ │ ├── VFParser.java
│ │ │ │ ├── VFParserBaseListener.java
│ │ │ │ ├── VFParserBaseVisitor.java
│ │ │ │ ├── VFParserListener.java
│ │ │ │ └── VFParserVisitor.java
│ │ └── scala
│ │ │ └── com
│ │ │ └── nawforce
│ │ │ └── runtime
│ │ │ ├── cmds
│ │ │ └── Scan.scala
│ │ │ ├── package.scala
│ │ │ ├── parsers
│ │ │ ├── CodeParser.scala
│ │ │ ├── CollectingErrorListener.scala
│ │ │ ├── PageParser.scala
│ │ │ ├── Source.scala
│ │ │ ├── SourceData.scala
│ │ │ └── TreeVisitor.scala
│ │ │ ├── platform
│ │ │ ├── Environment.scala
│ │ │ └── Path.scala
│ │ │ └── xml
│ │ │ └── XMLDocument.scala
│ │ └── test
│ │ └── scala
│ │ └── com
│ │ └── nawforce
│ │ └── runtime
│ │ └── FileSystemHelper.scala
├── pkgforce.iml
├── pom.xml
├── project
│ ├── build.properties
│ └── plugins.sbt
└── shared
│ └── src
│ ├── main
│ └── scala
│ │ └── com
│ │ └── nawforce
│ │ └── pkgforce
│ │ ├── diagnostics
│ │ ├── Diagnostic.scala
│ │ ├── Duplicates.scala
│ │ ├── Issue.scala
│ │ ├── IssueLogger.scala
│ │ └── Logger.scala
│ │ ├── documents
│ │ ├── DocumentIndex.scala
│ │ ├── MetadataDocument.scala
│ │ ├── ParsedCache.scala
│ │ └── SourceInfo.scala
│ │ ├── memory
│ │ ├── Cleanable.scala
│ │ ├── IdentityBox.scala
│ │ ├── IdentityEquality.scala
│ │ └── InternCache.scala
│ │ ├── modifiers
│ │ ├── FieldModifiers.scala
│ │ ├── MethodModifiers.scala
│ │ ├── Modifier.scala
│ │ └── ModifierResults.scala
│ │ ├── names
│ │ ├── DotName.scala
│ │ ├── EncodedName.scala
│ │ ├── Identifier.scala
│ │ ├── Name.scala
│ │ ├── Names.scala
│ │ ├── TypeIdentifier.scala
│ │ └── TypeName.scala
│ │ ├── parsers
│ │ ├── ApexClassSummary.scala
│ │ ├── ApexClassVisitor.scala
│ │ └── UTF8Decode.scala
│ │ ├── path
│ │ ├── Location.scala
│ │ ├── PathFactory.scala
│ │ └── PathLike.scala
│ │ ├── sfdx
│ │ ├── ForceIgnore.scala
│ │ ├── ModuleDependent.scala
│ │ ├── PackageDependent.scala
│ │ ├── PackageDirectory.scala
│ │ ├── PositionParser.scala
│ │ ├── SFDXProject.scala
│ │ ├── VersionNumber.scala
│ │ ├── WorkspaceConfig.scala
│ │ └── package.scala
│ │ ├── stream
│ │ ├── ApexGenerator.scala
│ │ ├── ComponentGenerator.scala
│ │ ├── FlowGenerator.scala
│ │ ├── LabelGenerator.scala
│ │ ├── PackageStream.scala
│ │ ├── PageGenerator.scala
│ │ ├── SObjectGenerator.scala
│ │ ├── TriggerGenerator.scala
│ │ └── VFEvent.scala
│ │ ├── workspace
│ │ ├── Layer.scala
│ │ └── Workspace.scala
│ │ └── xml
│ │ ├── XMLDocumentLike.scala
│ │ └── XMLFactory.scala
│ └── test
│ └── scala
│ └── com
│ └── nawforce
│ └── pkgforce
│ ├── diagnostics
│ └── LoggerTest.scala
│ ├── documents
│ ├── DocumentIndexTest.scala
│ ├── DocumentTest.scala
│ ├── ForceIgnoreTests.scala
│ ├── IgnoreRuleTest.scala
│ ├── ParsedCacheTest.scala
│ ├── PathTest.scala
│ └── XMLDocumentTest.scala
│ ├── modifiers
│ ├── ClassModifierTest.scala
│ ├── FieldModifierTest.scala
│ └── MethodModifierTest.scala
│ ├── names
│ ├── EncodedNameTest.scala
│ ├── IdentifierTest.scala
│ ├── TypeIdentifierTest.scala
│ └── TypeNameTest.scala
│ ├── parsers
│ ├── CodeParserTest.scala
│ ├── SOQLParserTest.scala
│ ├── SOSLParserTest.scala
│ ├── SourceDataTest.scala
│ ├── SummaryTest.scala
│ └── VFParserTest.scala
│ ├── sfdx
│ ├── ProjectLayerTest.scala
│ └── ProjectTest.scala
│ └── workspace
│ └── WorkspaceTest.scala
├── pom.xml
└── samples
├── Cumulus
└── sfdx-project.json
├── FindNearby
└── sfdx-project.json
├── HyperBatch
└── sfdx-project.json
├── Interactions-for-Student-Recruitment
├── extra
│ ├── DmlWrapper.cls
│ └── README.md
└── sfdx-project.json
├── NPSP
└── sfdx-project.json
├── README.md
├── at4dx
└── sfdx-project.json
├── fflib-apex-common-samplecode
└── sfdx-project.json
├── purealoe-lwc
├── .forceignore
└── sfdx-project.json
└── synthetic
├── dependency-counts
├── .forceignore
├── .gitignore
├── force-app
│ └── main
│ │ └── default
│ │ └── classes
│ │ ├── NoDeps.cls
│ │ ├── NoDeps.cls-meta.xml
│ │ ├── SingleDep.cls
│ │ ├── SingleDep.cls-meta.xml
│ │ ├── TestDep.cls
│ │ ├── TestDep.cls-meta.xml
│ │ ├── TransDep.cls
│ │ └── TransDep.cls-meta.xml
└── sfdx-project.json
├── mdapi-test
├── Hello.cls
├── Hello.cls-meta.xml
├── World.cls
└── World.cls-meta.xml
├── sfdx-ns-test
├── .forceignore
├── .gitignore
├── force-app
│ └── main
│ │ └── default
│ │ └── classes
│ │ ├── DoubleError.cls
│ │ ├── DoubleError.cls-meta.xml
│ │ ├── Hello.cls
│ │ ├── Hello.cls-meta.xml
│ │ ├── SingleError.cls
│ │ └── SingleError.cls-meta.xml
└── sfdx-project.json
├── sfdx-test
├── .forceignore
├── .gitignore
├── force-app
│ └── main
│ │ └── default
│ │ └── classes
│ │ ├── Hello.cls
│ │ └── Hello.cls-meta.xml
└── sfdx-project.json
└── test-classes
├── .forceignore
├── .gitignore
├── force-app
└── main
│ └── default
│ └── classes
│ ├── API.cls
│ ├── APIFactory.cls
│ ├── APIImpl.cls
│ ├── APITest.cls
│ ├── Base.cls
│ ├── BaseTest.cls
│ ├── Derived.cls
│ ├── DerivedTest.cls
│ ├── Hello.cls
│ ├── Hello.cls-meta.xml
│ ├── HelloTest.cls
│ ├── HelloTest.cls-meta.xml
│ ├── InnerServiceImpl.cls
│ ├── NoTest.cls
│ ├── NoTest.cls-meta.xml
│ ├── Service.cls
│ ├── ServiceAPITest.cls
│ ├── ServiceImpl.cls
│ └── ServiceTest.cls
└── sfdx-project.json
/.github/workflows/WinBuild.yml:
--------------------------------------------------------------------------------
1 | name: WinBuild
2 |
3 | on:
4 | workflow_dispatch:
5 |
6 | jobs:
7 | build:
8 |
9 | runs-on: windows-latest
10 |
11 | steps:
12 | - run: git config --global core.autocrlf false
13 | - uses: actions/checkout@v2
14 | - uses: olafurpg/setup-scala@v10
15 |
16 | - name: Set up JDK 1.8
17 | uses: actions/setup-java@v2
18 | with:
19 | distribution: adopt
20 | java-version: 8
21 | cache: "maven"
22 |
23 | - name: Set up Maven
24 | uses: stCarolas/setup-maven@v4.2
25 | with:
26 | maven-version: 3.8.1
27 |
28 | - name: Build with Maven
29 | run: |
30 | mvn --version
31 | mvn -B install -D gpg.skip
32 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.scalafmt.conf:
--------------------------------------------------------------------------------
1 | version = 2.6.3
2 | continuationIndent.defnSite = 2
3 | optIn.configStyleArguments = false
4 | align.preset = more
5 | maxColumn = 100
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | [The "BSD licence"]
2 | Copyright (c) 2013 Terence Parr, Sam Harwell (ApexLexer.g4 & ApexParser.g4)
3 | Copyright (c) 2017-2020 Kevin Jones (All other contributions)
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions
8 | are met:
9 | 1. Redistributions of source code must retain the above copyright
10 | notice, this list of conditions and the following disclaimer.
11 | 2. Redistributions in binary form must reproduce the above copyright
12 | notice, this list of conditions and the following disclaimer in the
13 | documentation and/or other materials provided with the distribution.
14 | 3. The name of the author may not be used to endorse or promote products
15 | derived from this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 |
--------------------------------------------------------------------------------
/apexlink.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/apexlink/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # ANTLR
3 | *.tokens
4 | *.interp
5 |
6 | # Linked common directory
7 | module/common
8 |
9 | # scratch bin directory
10 | bin/
11 |
12 | # checkstyle junk
13 | .idea/checkstyle-idea.xml
14 |
15 | # Created by https://www.gitignore.io/api/windows,intellij,maven
16 |
17 | ### Windows ###
18 | # Windows image file caches
19 | Thumbs.db
20 | ehthumbs.db
21 |
22 | # Folder config file
23 | Desktop.ini
24 |
25 | # Recycle Bin used on file shares
26 | $RECYCLE.BIN/
27 |
28 | # Windows Installer files
29 | *.cab
30 | *.msi
31 | *.msm
32 | *.msp
33 |
34 | # Windows shortcuts
35 | *.lnk
36 |
37 |
38 | ### Intellij ###
39 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
40 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
41 |
42 | # User-specific stuff:
43 | #.idea/workspace.xml
44 | #.idea/tasks.xml
45 | #.idea/dictionaries/
46 |
47 | # Sensitive or high-churn files:
48 | #.idea/dataSources.ids
49 | #.idea/dataSources.xml
50 | #.idea/dataSources.local.xml
51 | #.idea/sqlDataSources.xml
52 | #.idea/dynamic.xml
53 | #.idea/uiDesigner.xml
54 |
55 | # Gradle:
56 | #.idea/gradle.xml
57 | ##.idea/libraries
58 |
59 | # Mongo Explorer plugin:
60 | #.idea/mongoSettings.xml
61 |
62 | ## File-based project format:
63 | *.iws
64 |
65 | ## Plugin-specific files:
66 |
67 | # IntelliJ
68 | /out/
69 |
70 | # mpeltonen/sbt-idea plugin
71 | .idea_modules/
72 |
73 | # JIRA plugin
74 | atlassian-ide-plugin.xml
75 |
76 | # Crashlytics plugin (for Android Studio and IntelliJ)
77 | com_crashlytics_export_strings.xml
78 | crashlytics.properties
79 | crashlytics-build.properties
80 | fabric.properties
81 |
82 | ### Intellij Patch ###
83 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
84 |
85 | # *.iml
86 | # modules.xml
87 | # .idea/misc.xml
88 | # *.ipr
89 |
90 |
91 | ### Maven ###
92 | target/
93 | pom.xml.tag
94 | pom.xml.releaseBackup
95 | pom.xml.versionsBackup
96 | pom.xml.next
97 | release.properties
98 | dependency-reduced-pom.xml
99 | buildNumber.properties
100 | .mvn/timing.properties
101 |
102 |
--------------------------------------------------------------------------------
/apexlink/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /workspace.xml
--------------------------------------------------------------------------------
/apexlink/.idea/.idea/.idea.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/apexlink/.idea/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/apexlink/.idea/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 1.7
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/apexlink/.idea/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/apexlink/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/apexlink/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/apexlink/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/apexlink/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/apexlink/.idea/dictionaries/kevin.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | declarators
5 | deployer
6 | fieldsets
7 | intelli
8 | jsonrpc
9 | multiselect
10 | nawforce
11 | pkgforce
12 | shogowada
13 | tostring
14 | unmanaged
15 | upickle
16 |
17 |
18 |
--------------------------------------------------------------------------------
/apexlink/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/apexlink/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__com_github_nawforce_scala_json_rpc_2_13_1_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__com_github_nawforce_scala_json_rpc_upickle_json_serializer_2_13_1_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__com_google_guava_guava_18_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__com_google_jimfs_jimfs_1_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__com_lihaoyi_geny_2_13_0_6_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__com_lihaoyi_ujson_2_13_1_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__com_lihaoyi_upack_2_13_1_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__com_lihaoyi_upickle_2_13_1_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__com_lihaoyi_upickle_core_2_13_1_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__com_lihaoyi_upickle_implicits_2_13_1_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_antlr_antlr4_runtime_4_8_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scala_js_scalajs_stubs_2_13_1_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scala_lang_modules_scala_collection_compat_2_13_2_1_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scala_lang_modules_scala_parallel_collections_2_13_1_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scala_lang_modules_scala_xml_2_13_1_3_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scala_lang_scala_library_2_13_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Scala_2_13
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scala_lang_scala_reflect_2_13_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scalactic_scalactic_2_13_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scalatest_scalatest_2_13_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scalatest_scalatest_compatible_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scalatest_scalatest_core_2_13_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scalatest_scalatest_diagrams_2_13_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scalatest_scalatest_featurespec_2_13_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scalatest_scalatest_flatspec_2_13_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scalatest_scalatest_freespec_2_13_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scalatest_scalatest_funspec_2_13_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scalatest_scalatest_funsuite_2_13_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scalatest_scalatest_matchers_core_2_13_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scalatest_scalatest_mustmatchers_2_13_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scalatest_scalatest_propspec_2_13_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scalatest_scalatest_refspec_2_13_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scalatest_scalatest_shouldmatchers_2_13_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/libraries/Maven__org_scalatest_scalatest_wordspec_2_13_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apexlink/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/apexlink/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/apexlink/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/apexlink/.idea/scala_compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/apexlink/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/apexlink/.scalafmt.conf:
--------------------------------------------------------------------------------
1 | version = 2.6.3
2 | continuationIndent.defnSite = 2
3 | optIn.configStyleArguments = false
4 | align.preset = more
5 | maxColumn = 100
6 |
--------------------------------------------------------------------------------
/apexlink/images/FindZombies.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nawforce/apex-link/7688adcb7a2d7f8aa28d0618ffb2a3aa81151858/apexlink/images/FindZombies.png
--------------------------------------------------------------------------------
/apexlink/images/UnusedField.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nawforce/apex-link/7688adcb7a2d7f8aa28d0618ffb2a3aa81151858/apexlink/images/UnusedField.png
--------------------------------------------------------------------------------
/apexlink/src/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Main-Class: com.nawforce.apexlink.ApexLink
3 | Class-Path:
4 | antlr4-runtime-4.8-1.jar
5 | apex-parser-3.0.0.jar
6 | geny_2.13-0.6.2.jar
7 | pkgforce_2.13-2.3.7.jar
8 | runforce-55.5.0.jar
9 | scala-collection-compat_2.13-2.1.4.jar
10 | scala-json-rpc-upickle-json-serializer_2.13-1.0.1.jar
11 | scala-json-rpc_2.13-1.0.1.jar
12 | scala-library-2.13.3.jar
13 | scala-parallel-collections_2.13-1.0.0.jar
14 | scala-reflect-2.13.3.jar
15 | scala-xml_2.13-1.3.0.jar
16 | ujson_2.13-1.2.0.jar
17 | upack_2.13-1.2.0.jar
18 | upickle-core_2.13-1.2.0.jar
19 | upickle-implicits_2.13-1.2.0.jar
20 | upickle_2.13-1.2.0.jar
21 |
--------------------------------------------------------------------------------
/apexlink/src/main/scala/com/nawforce/apexlink/ApexLink.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.apexlink
16 |
17 | import com.nawforce.apexlink.cmds.Check
18 |
19 | object ApexLink {
20 | def main(args: Array[String]): Unit = {
21 | System.exit(Check.run(args))
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/apexlink/src/main/scala/com/nawforce/apexlink/api/ServerOps.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.apexlink.api
16 |
17 | /** Collection of Ops functions for changing global behaviours */
18 | object ServerOps {
19 | private var lazyBlocks: Boolean = true
20 | private var duplicateObjectMonitor: Boolean = false
21 | private var autoFlush: Boolean = true
22 |
23 | /** Are we using lazy blocks, this is enabled by default */
24 | def getLazyBlocks: Boolean = {
25 | lazyBlocks
26 | }
27 |
28 | /** Update lazy block flag */
29 | def setLazyBlocks(enable: Boolean): Unit = {
30 | lazyBlocks = enable
31 | }
32 |
33 | /** Is duplicate object monitor enabled, this is disabled by default */
34 | def getDuplicateObjectMonitoring: Boolean = {
35 | duplicateObjectMonitor
36 | }
37 |
38 | /** Update duplicate object monitor flag */
39 | def setDuplicateObjectMonitoring(enable: Boolean): Unit = {
40 | duplicateObjectMonitor = enable
41 | }
42 |
43 | /** Is auto flushing, this is enabled by default */
44 | def getAutoFlush: Boolean = {
45 | autoFlush
46 | }
47 |
48 | /** Update auto flushing flag */
49 | def setAutoFlush(enable: Boolean): Boolean = {
50 | val current = autoFlush
51 | autoFlush = enable
52 | current
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/apexlink/src/main/scala/com/nawforce/apexlink/cmds/Server.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.apexlink.cmds
16 |
17 | import com.nawforce.apexlink.rpc.RPCServer
18 |
19 | object Server {
20 |
21 | def main(args: Array[String]): Unit = {
22 | try {
23 | new RPCServer().run()
24 | } catch {
25 | case ex: Throwable =>
26 | ex.printStackTrace()
27 | System.exit(-1)
28 | }
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/apexlink/src/main/scala/com/nawforce/apexlink/deps/TransitiveCollector.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.apexlink.deps
16 |
17 | import com.nawforce.apexlink.api.Org
18 | import com.nawforce.pkgforce.names.{Name, Names, TypeIdentifier}
19 |
20 | import scala.collection.mutable
21 |
22 | /** Transitive dependency helper */
23 | class TransitiveCollector(org: Org, apexOnly: Boolean) {
24 | private val packagesByNamespace =
25 | org.getPackages().map(pkg => (Name(pkg.getNamespaces(false).head), pkg)).toMap
26 |
27 | def count(id: TypeIdentifier, ignoring: Array[TypeIdentifier]): Int = {
28 | transitives(id, ignoring).length
29 | }
30 |
31 | def transitives(
32 | id: TypeIdentifier,
33 | ignoring: Array[TypeIdentifier] = Array()
34 | ): Array[TypeIdentifier] = {
35 | val pkg = packagesByNamespace.get(id.namespace.getOrElse(Names.Empty))
36 |
37 | val depsSeen = mutable.Set[TypeIdentifier]()
38 | depsSeen.add(id)
39 | ignoring.foreach(i => depsSeen.add(i))
40 | val deps = mutable.ArrayBuffer[TypeIdentifier]()
41 | deps.append(id)
42 | var current = 0
43 | while (current < deps.size) {
44 | pkg
45 | .flatMap(pkg => {
46 | Option(pkg.getDependencies(deps(current), outerInheritanceOnly = false, apexOnly))
47 | })
48 | .getOrElse(Array[TypeIdentifier]())
49 | .filterNot(depsSeen.contains)
50 | .foreach(t => {
51 | deps.append(t)
52 | depsSeen.add(t)
53 | })
54 | current += 1
55 | }
56 | deps.remove(0)
57 | deps.toArray
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/apexlink/src/main/scala/com/nawforce/apexlink/finding/TypeError.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.apexlink.finding
16 |
17 | import com.nawforce.pkgforce.diagnostics.{Diagnostic, Issue, MISSING_CATEGORY}
18 | import com.nawforce.pkgforce.names.TypeName
19 | import com.nawforce.pkgforce.path.PathLocation
20 |
21 | /** Collection of error types returned from type requests */
22 | sealed abstract class TypeError(val typeName: TypeName) {
23 | def asIssue(location: PathLocation): Issue
24 |
25 | // Protect against old way of using this
26 | override def toString: String = throw new IllegalArgumentException
27 | }
28 |
29 | final case class MissingType(_typeName: TypeName) extends TypeError(_typeName) {
30 | def asIssue(location: PathLocation): Issue = {
31 | new Issue(
32 | location.path,
33 | Diagnostic(MISSING_CATEGORY, location.location, s"No type declaration found for '$typeName'")
34 | )
35 | }
36 |
37 | // Protect against old way of using this
38 | override def toString: String = throw new IllegalArgumentException
39 | }
40 |
41 | final case class WrongTypeArguments(_typeName: TypeName, expected: Integer)
42 | extends TypeError(_typeName) {
43 | def asIssue(location: PathLocation): Issue = {
44 | new Issue(
45 | location.path,
46 | Diagnostic(
47 | MISSING_CATEGORY,
48 | location.location,
49 | s"Wrong number of type arguments for '$typeName', expected $expected"
50 | )
51 | )
52 | }
53 |
54 | // Protect against old way of using this
55 | override def toString: String = throw new IllegalArgumentException
56 | }
57 |
--------------------------------------------------------------------------------
/apexlink/src/main/scala/com/nawforce/apexlink/memory/Monitor.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.apexlink.memory
15 |
16 | import com.nawforce.apexlink.api.ServerOps
17 | import com.nawforce.apexlink.types.core.TypeDeclaration
18 | import com.nawforce.pkgforce.diagnostics.LoggerOps
19 |
20 | object Monitor {
21 | val map = new SkinnyWeakSet[AnyRef]()
22 | var duplicateTypes: SkinnyWeakSet[TypeDeclaration] = _
23 |
24 | def push[T <: AnyRef](t: T): Unit = {
25 | if (ServerOps.getDuplicateObjectMonitoring)
26 | map.add(t)
27 | }
28 |
29 | def size: Int = map.size
30 |
31 | def reportDuplicateTypes(): Unit = {
32 | if (ServerOps.getDuplicateObjectMonitoring) {
33 | val tdsByName = map.toSet.toArray.collect { case td: TypeDeclaration => (td.typeName, td) }
34 | val typeNames = tdsByName.map(_._1)
35 | val duplicates = typeNames.toSeq.groupBy(identity).collect { case (t, Seq(_, _, _*)) => t }
36 | if (duplicates.nonEmpty) {
37 | duplicates.foreach(typeName => {
38 | LoggerOps.debug(s"Duplicate types found for $typeName")
39 | })
40 | duplicateTypes = new SkinnyWeakSet[TypeDeclaration]()
41 | duplicates.foreach(
42 | dup => tdsByName.filter(_._1 == dup).foreach(x => duplicateTypes.add(x._2))
43 | )
44 | }
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/apexlink/src/main/scala/com/nawforce/apexlink/memory/SkinnySet.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.apexlink.memory
16 |
17 | import scala.collection.mutable
18 |
19 | /** Low memory set. Uses an array for small sizes before swapping to a set. */
20 | final class SkinnySet[T <: AnyRef] {
21 | private var arrayOf: mutable.ArrayBuffer[T] = _
22 | private var setOf: mutable.Set[T] = _
23 |
24 | def isEmpty: Boolean = {
25 | if (setOf != null)
26 | setOf.isEmpty
27 | else if (arrayOf != null)
28 | arrayOf.isEmpty
29 | else
30 | true
31 | }
32 |
33 | def nonEmpty: Boolean = !isEmpty
34 |
35 | def size: Int = {
36 | if (setOf != null)
37 | setOf.size
38 | else if (arrayOf != null)
39 | arrayOf.size
40 | else
41 | 0
42 | }
43 |
44 | def add(t: T): Unit = {
45 | if (setOf != null)
46 | setOf.add(t)
47 | else {
48 | if (arrayOf == null)
49 | arrayOf = new mutable.ArrayBuffer[T](4)
50 | arrayOf.append(t)
51 | if (arrayOf.size > 64)
52 | arrayOf = arrayOf.distinct
53 | }
54 |
55 | if (arrayOf != null && arrayOf.length > 64) {
56 | setOf = new mutable.HashSet[T]()
57 | arrayOf.foreach(setOf.add)
58 | arrayOf = null
59 | }
60 | }
61 |
62 | def toSet: Set[T] = {
63 | if (setOf != null)
64 | setOf.toSet
65 | else if (arrayOf != null)
66 | arrayOf.toSet
67 | else
68 | Set.empty
69 | }
70 |
71 | def toIterable: mutable.Iterable[T] = {
72 | if (setOf != null) {
73 | setOf
74 | } else if (arrayOf != null) {
75 | arrayOf = arrayOf.distinct
76 | arrayOf
77 | } else {
78 | mutable.Iterable()
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/apexlink/src/main/scala/com/nawforce/apexlink/names/TypeIdentifiers.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.apexlink.names
15 |
16 | import com.nawforce.apexlink.names.TypeNames.TypeNameUtils
17 | import com.nawforce.pkgforce.names.{Names, TypeIdentifier}
18 |
19 | object TypeIdentifiers {
20 | implicit class TypeIdentifierUtils(typeIdentifier: TypeIdentifier) {
21 |
22 | def intern: TypeIdentifier =
23 | TypeIdentifier(typeIdentifier.namespace.map(Names(_)), typeIdentifier.typeName.intern)
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/apexlink/src/main/scala/com/nawforce/apexlink/plugins/Plugin.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.apexlink.plugins
15 |
16 | import com.nawforce.apexlink.cst._
17 | import com.nawforce.apexlink.plugins.Plugin.emptyTypes
18 | import com.nawforce.apexlink.types.apex.{SummaryDeclaration, TriggerDeclaration}
19 | import com.nawforce.apexlink.types.core.DependentType
20 |
21 | class Plugin(td: DependentType) {
22 |
23 | def onTypeValidated(): Seq[DependentType] = {
24 | td match {
25 | case td: ClassDeclaration => onClassValidated(td)
26 | case td: InterfaceDeclaration => onInterfaceValidated(td)
27 | case td: EnumDeclaration => onEnumValidated(td)
28 | case td: TriggerDeclaration => onTriggerValidated(td)
29 | case td: SummaryDeclaration => onSummaryValidated(td)
30 | case _ => emptyTypes
31 | }
32 | }
33 |
34 | def onClassValidated(td: ClassDeclaration): Seq[DependentType] = emptyTypes
35 |
36 | def onInterfaceValidated(td: InterfaceDeclaration): Seq[DependentType] = emptyTypes
37 |
38 | def onEnumValidated(td: EnumDeclaration): Seq[DependentType] = emptyTypes
39 |
40 | def onTriggerValidated(td: TriggerDeclaration): Seq[DependentType] = emptyTypes
41 |
42 | def onSummaryValidated(td: SummaryDeclaration): Seq[DependentType] = emptyTypes
43 |
44 | def onBlockValidated(block: Block, isStatic: Boolean, context: BlockVerifyContext): Unit = {}
45 | }
46 |
47 | object Plugin {
48 | val emptyTypes: Seq[DependentType] = Seq.empty
49 | }
50 |
--------------------------------------------------------------------------------
/apexlink/src/main/scala/com/nawforce/apexlink/plugins/PluginDispatcher.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.apexlink.plugins
16 |
17 | import com.nawforce.apexlink.cst.{Block, BlockVerifyContext}
18 | import com.nawforce.apexlink.types.core.DependentType
19 |
20 | import java.lang.reflect.Constructor
21 |
22 | class PluginDispatcher(td: DependentType, plugins: Seq[Plugin]) extends Plugin(td) {
23 |
24 | override def onTypeValidated(): Seq[DependentType] = {
25 | plugins.flatMap(_.onTypeValidated())
26 | }
27 |
28 | override def onBlockValidated(
29 | block: Block,
30 | isStatic: Boolean,
31 | context: BlockVerifyContext
32 | ): Unit = {
33 | plugins.foreach(_.onBlockValidated(block, isStatic, context))
34 | }
35 | }
36 |
37 | object PluginDispatcher {
38 | def apply(td: DependentType, plugins: Seq[Constructor[_ <: Plugin]]): PluginDispatcher = {
39 | new PluginDispatcher(
40 | td,
41 | plugins.map(plugin => {
42 | plugin.newInstance(td)
43 | })
44 | )
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/apexlink/src/main/scala/com/nawforce/apexlink/rpc/CompletionItemLink.scala:
--------------------------------------------------------------------------------
1 | package com.nawforce.apexlink.rpc
2 |
3 | import com.nawforce.apexlink.types.core.{FieldDeclaration, MethodDeclaration, TypeDeclaration}
4 | import com.nawforce.pkgforce.parsers.{CLASS_NATURE, ENUM_NATURE, INTERFACE_NATURE}
5 | import com.nawforce.pkgforce.path.Location
6 | import io.github.shogowada.scala.jsonrpc.serializers.JSONRPCPickler.{macroRW, ReadWriter => RW}
7 |
8 | case class CompletionItemLink(label: String, kind: String, detail: String = null)
9 |
10 | object CompletionItemLink {
11 | implicit val rw: RW[CompletionItemLink] = macroRW
12 | implicit val rwLocation: RW[Location] = macroRW
13 |
14 | def apply(td: TypeDeclaration): Option[CompletionItemLink] = {
15 | val detail = td.modifiers.map(_.name).mkString(" ")
16 | td.nature match {
17 | case CLASS_NATURE => Some(CompletionItemLink(td.typeName.name.value, "Class", detail))
18 | case INTERFACE_NATURE => Some(CompletionItemLink(td.typeName.name.value, "Interface", detail))
19 | case ENUM_NATURE => Some(CompletionItemLink(td.typeName.name.value, "Enum", detail))
20 | case _ => None
21 | }
22 | }
23 |
24 | def apply(field: FieldDeclaration): CompletionItemLink = {
25 | CompletionItemLink(field.name.toString, "Field", field.toString)
26 | }
27 |
28 | def apply(method: MethodDeclaration): CompletionItemLink = {
29 | CompletionItemLink(
30 | method.name.toString + "(" + method.parameters.map(_.name.toString()).mkString(", ") + ")",
31 | "Method",
32 | method.toString
33 | )
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/apexlink/src/main/scala/com/nawforce/apexlink/rpc/LocationLink.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.apexlink.rpc
15 |
16 | import com.nawforce.pkgforce.path.Location
17 | import io.github.shogowada.scala.jsonrpc.serializers.JSONRPCPickler.{macroRW, ReadWriter => RW}
18 |
19 | /** A link for a given position, can be used for definition or reference links. origin is the calculated extent of
20 | * the link that was selected. targetPath is where the definition or reference refers to. Within target path, target
21 | * is the full extend of the definition whereas targetSelection is just the extent of the link itself.
22 | */
23 | case class LocationLink(
24 | origin: Location,
25 | targetPath: String,
26 | target: Location,
27 | targetSelection: Location
28 | )
29 |
30 | object LocationLink {
31 | implicit val rw: RW[LocationLink] = macroRW
32 | implicit val rwLocation: RW[Location] = macroRW
33 | }
34 |
--------------------------------------------------------------------------------
/apexlink/src/main/scala/com/nawforce/apexlink/types/core/BasicTypeDeclaration.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.apexlink.types.core
16 |
17 | import com.nawforce.apexlink.org.Module
18 | import com.nawforce.pkgforce.modifiers.{Modifier, ModifierOps}
19 | import com.nawforce.pkgforce.names.{Name, TypeName}
20 | import com.nawforce.pkgforce.parsers.{CLASS_NATURE, Nature}
21 | import com.nawforce.pkgforce.path.PathLike
22 |
23 | import scala.collection.immutable.ArraySeq
24 |
25 | class BasicTypeDeclaration(val paths: ArraySeq[PathLike], module: Module, val typeName: TypeName)
26 | extends TypeDeclaration {
27 |
28 | override val moduleDeclaration: Option[Module] = Some(module)
29 | override val name: Name = typeName.name
30 | override val outerTypeName: Option[TypeName] = None
31 | override val nature: Nature = CLASS_NATURE
32 | override val modifiers: ArraySeq[Modifier] = ModifierOps.emptyModifiers
33 | override lazy val isComplete: Boolean = true
34 |
35 | override val superClass: Option[TypeName] = None
36 | override val interfaces: ArraySeq[TypeName] = ArraySeq()
37 | override def nestedTypes: ArraySeq[TypeDeclaration] = TypeDeclaration.emptyTypeDeclarations
38 |
39 | override val blocks: ArraySeq[BlockDeclaration] = BlockDeclaration.emptyBlockDeclarations
40 | override val fields: ArraySeq[FieldDeclaration] = FieldDeclaration.emptyFieldDeclarations
41 | override val constructors: ArraySeq[ConstructorDeclaration] =
42 | ConstructorDeclaration.emptyConstructorDeclarations
43 | override val methods: ArraySeq[MethodDeclaration] = MethodDeclaration.emptyMethodDeclarations
44 |
45 | override def validate(): Unit = {}
46 | }
47 |
48 | class InnerBasicTypeDeclaration(_paths: ArraySeq[PathLike], _module: Module, _typeName: TypeName)
49 | extends BasicTypeDeclaration(_paths, _module, _typeName) {
50 | override val outerTypeName: Option[TypeName] = typeName.outer
51 | }
52 |
--------------------------------------------------------------------------------
/apexlink/src/main/scala/com/nawforce/apexlink/types/core/TypeId.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.apexlink.types.core
16 |
17 | import com.nawforce.apexlink.org.Module
18 | import com.nawforce.pkgforce.names.{TypeIdentifier, TypeName}
19 |
20 | case class TypeId(module: Module, typeName: TypeName) {
21 | def asTypeIdentifier: TypeIdentifier = {
22 | TypeIdentifier(module.pkg.namespace, typeName)
23 | }
24 |
25 | override def toString: String = asTypeIdentifier.toString
26 | }
27 |
--------------------------------------------------------------------------------
/apexlink/src/main/scala/com/nawforce/apexlink/types/other/AnyDeclaration.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.apexlink.types.other
16 |
17 | import com.nawforce.apexlink.names.TypeNames
18 | import com.nawforce.apexlink.org.Module
19 | import com.nawforce.apexlink.types.core.BasicTypeDeclaration
20 | import com.nawforce.pkgforce.path.PathLike
21 |
22 | /** An any type declaration, there are deliberately very few uses of this, hopefully at some point it
23 | * can be removed.
24 | */
25 | final case class AnyDeclaration(module: Module)
26 | extends BasicTypeDeclaration(PathLike.emptyPaths, module, TypeNames.Any)
27 |
--------------------------------------------------------------------------------
/apexlink/src/test/scala/com/nawforce/apexlink/FileSystemHelper.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.apexlink
15 |
16 | import java.nio.file.Files
17 |
18 | import com.google.common.jimfs.{Configuration, Jimfs}
19 | import com.nawforce.pkgforce.documents.ParsedCache
20 | import com.nawforce.pkgforce.path.PathLike
21 | import com.nawforce.runtime.platform.Path
22 |
23 | object FileSystemHelper {
24 |
25 | // Abstract virtual filesystem for testing
26 | def run[T](files: Map[String, String])(verify: PathLike => T): T = {
27 | val config = Configuration
28 | .unix()
29 | .toBuilder
30 | .setWorkingDirectory("/")
31 | .build()
32 | val fs = Jimfs.newFileSystem(config)
33 | val rootDir = fs.getRootDirectories.iterator().next()
34 | files.foreach(kv => {
35 | val path = rootDir.resolve(kv._1)
36 | Files.createDirectories(path.getParent)
37 | Files.write(path, kv._2.getBytes())
38 | })
39 |
40 | ParsedCache.clear()
41 | verify(new Path(rootDir))
42 | }
43 |
44 | // Temp directory based model
45 | def runTempDir[T](files: Map[String, String], setupCache: Boolean = false)(
46 | verify: PathLike => T
47 | ): T = {
48 | val tempDir = Files.createTempDirectory("apexlinktest")
49 | files.foreach(kv => {
50 | val path = tempDir.resolve(kv._1)
51 | Files.createDirectories(path.getParent)
52 | Files.write(path, kv._2.getBytes())
53 | })
54 |
55 | // Make sure cache is empty if we are going to use it
56 | if (setupCache)
57 | ParsedCache.clear()
58 |
59 | try {
60 | verify(new Path(tempDir))
61 | } finally {
62 | files.foreach(kv => {
63 | val path = tempDir.resolve(kv._1)
64 | path.toFile.delete()
65 | })
66 | tempDir.toFile.delete()
67 | }
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/apexlink/src/test/scala/com/nawforce/apexlink/cst/ArrayTest.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.apexlink.cst
16 |
17 | import com.nawforce.apexlink.TestHelper
18 | import org.scalatest.funsuite.AnyFunSuite
19 |
20 | class ArrayTest extends AnyFunSuite with TestHelper {
21 |
22 | test("Non-Integer index") {
23 | typeDeclaration("public class Dummy {Integer b; {List a; b = a[null].b;}}")
24 | assert(dummyIssues == "Error: line 1 at 54-58: Array indexes must be Integers, found 'null'\n")
25 | }
26 |
27 | test("Integer index") {
28 | typeDeclaration("public class Dummy {Integer b; {List a; b = a[0].b;}}")
29 | assert(dummyIssues.isEmpty)
30 | }
31 |
32 | test("Assignment") {
33 | typeDeclaration("public class Dummy {{String[] a; a=new String[]{'a'}; }}")
34 | assert(dummyIssues.isEmpty)
35 | }
36 |
37 | // TODO: Complete testing
38 | }
39 |
--------------------------------------------------------------------------------
/apexlink/src/test/scala/com/nawforce/apexlink/cst/AssignTest.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.apexlink.cst
16 |
17 | import com.nawforce.apexlink.{FileSystemHelper, TestHelper}
18 | import com.nawforce.pkgforce.path.PathLike
19 | import org.scalatest.funsuite.AnyFunSuite
20 |
21 | class AssignTest extends AnyFunSuite with TestHelper {
22 |
23 | test("Assign list of ghosted SObject to SObject list") {
24 | FileSystemHelper.run(
25 | Map(
26 | "sfdx-project.json" ->
27 | """{
28 | |"packageDirectories": [{"path": "force-app"}],
29 | |"plugins": {"dependencies": [{"namespace": "ext"}]}
30 | |}""".stripMargin,
31 | "force-app/Dummy.cls" -> "public class Dummy { {List b; List a = b;} }"
32 | )
33 | ) { root: PathLike =>
34 | createHappyOrg(root)
35 | }
36 | }
37 |
38 | test("Assign list of ghosted types to Object list") {
39 | FileSystemHelper.run(
40 | Map(
41 | "sfdx-project.json" ->
42 | """{
43 | |"packageDirectories": [{"path": "force-app"}],
44 | |"plugins": {"dependencies": [{"namespace": "ext"}]}
45 | |}""".stripMargin,
46 | "force-app/Dummy.cls" -> "public class Dummy { {List b; List a = b;} }"
47 | )
48 | ) { root: PathLike =>
49 | createHappyOrg(root)
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/apexlink/src/test/scala/com/nawforce/apexlink/cst/ConstructorTest.scala:
--------------------------------------------------------------------------------
1 | package com.nawforce.apexlink.cst
2 |
3 | import com.nawforce.apexlink.TestHelper
4 | import org.scalatest.funsuite.AnyFunSuite
5 |
6 | class ConstructorTest extends AnyFunSuite with TestHelper {
7 |
8 | test("Basic constructor") {
9 | typeDeclaration("public class Dummy {public dummY() {}}")
10 | assert(dummyIssues.isEmpty)
11 | }
12 |
13 | test("Bad name constructor") {
14 | typeDeclaration("public class Dummy {public Foo() {}}")
15 | assert(
16 | dummyIssues ==
17 | "Error: line 1 at 27-30: Constructors should have same name as the class, maybe method return type is missing?\n"
18 | )
19 | }
20 |
21 | test("Duplicate no args constructor") {
22 | typeDeclaration("public class Dummy {public Dummy() {} private Dummy() {}}")
23 | assert(
24 | dummyIssues ==
25 | "Error: line 1 at 46-51: Constructor is a duplicate of an earlier constructor at line 1 at 27-32\n"
26 | )
27 | }
28 |
29 | test("Duplicate same single args constructor") {
30 | typeDeclaration("public class Dummy {public Dummy(String a) {} private Dummy(String b) {}}")
31 | assert(
32 | dummyIssues ==
33 | "Error: line 1 at 54-59: Constructor is a duplicate of an earlier constructor at line 1 at 27-32\n"
34 | )
35 | }
36 |
37 | test("Duplicate same multi args constructor") {
38 | typeDeclaration(
39 | "public class Dummy {public Dummy(String a, Integer b) {} private Dummy(String c, Integer d) {}}"
40 | )
41 | assert(
42 | dummyIssues ==
43 | "Error: line 1 at 65-70: Constructor is a duplicate of an earlier constructor at line 1 at 27-32\n"
44 | )
45 | }
46 |
47 | test("Duplicate same args (different typeRef) constructor") {
48 | typeDeclaration(
49 | "public class Dummy {public Dummy(String a) {} private Dummy(System.String b) {}}"
50 | )
51 | assert(
52 | dummyIssues ==
53 | "Error: line 1 at 54-59: Constructor is a duplicate of an earlier constructor at line 1 at 27-32\n"
54 | )
55 | }
56 |
57 | test("Multiple Duplicate no args constructor") {
58 | typeDeclaration("public class Dummy {public Dummy() {} private Dummy() {} private Dummy() {}}")
59 | assert(
60 | dummyIssues ==
61 | "Error: line 1 at 46-51: Constructor is a duplicate of an earlier constructor at line 1 at 27-32\n" +
62 | "Error: line 1 at 65-70: Constructor is a duplicate of an earlier constructor at line 1 at 27-32\n"
63 | )
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/apexlink/src/test/scala/com/nawforce/apexlink/cst/IfTest.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.apexlink.cst
16 |
17 | import com.nawforce.apexlink.TestHelper
18 | import org.scalatest.funsuite.AnyFunSuite
19 |
20 | class IfTest extends AnyFunSuite with TestHelper {
21 |
22 | test("Block bug") {
23 | typeDeclaration("public class Dummy {{ if (false) String a = ''; else a =''; }}")
24 | assert(!hasIssues)
25 | }
26 |
27 | // TODO: Write some tests!
28 | }
29 |
--------------------------------------------------------------------------------
/apexlink/src/test/scala/com/nawforce/apexlink/cst/SafeNavigationTest.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.apexlink.cst
15 |
16 | import com.nawforce.apexlink.TestHelper
17 | import org.scalatest.funsuite.AnyFunSuite
18 |
19 | class SafeNavigationTest extends AnyFunSuite with TestHelper {
20 |
21 | test("Field Reference") {
22 | typeDeclaration("public class Dummy {String a; { String b = this?.a; }}")
23 | assert(!hasIssues)
24 | }
25 |
26 | test("Method Reference") {
27 | typeDeclaration("public class Dummy {String func(){} { String b = this?.func(); }}")
28 | assert(!hasIssues)
29 | }
30 |
31 | test("Field nested reference") {
32 | typeDeclaration("public class Dummy {Dummy a; { Dummy b = this?.a?.a; }}")
33 | assert(!hasIssues)
34 | }
35 |
36 | test("Method nexted reference") {
37 | typeDeclaration("public class Dummy {Dummy func(){} { Dummy b = this?.func()?.func(); }}")
38 | assert(!hasIssues)
39 | }
40 |
41 | test("Static field reference") {
42 | typeDeclaration("public class Dummy {static String a; { String b = Dummy?.a; }}")
43 | assert(
44 | dummyIssues == "Error: line 1 at 50-58: Safe navigation operator (?.) can not be used on static references\n"
45 | )
46 | }
47 |
48 | test("Static method reference") {
49 | typeDeclaration("public class Dummy {static String func(){} { String b = Dummy?.func(); }}")
50 | assert(
51 | dummyIssues == "Error: line 1 at 56-69: Safe navigation operator (?.) can not be used on static references\n"
52 | )
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/apexlink/src/test/scala/com/nawforce/apexlink/cst/VariablesTest.scala:
--------------------------------------------------------------------------------
1 | package com.nawforce.apexlink.cst
2 |
3 | import com.nawforce.apexlink.TestHelper
4 | import org.scalatest.funsuite.AnyFunSuite
5 |
6 | class VariablesTest extends AnyFunSuite with TestHelper {
7 |
8 | test("Boolean variable declaration") {
9 | typeDeclaration("public class Dummy { {Boolean b = 1;} }")
10 | assert(
11 | dummyIssues == "Error: line 1 at 30-35: Incompatible types in assignment, from 'System.Integer' to 'System.Boolean'\n"
12 | )
13 | }
14 |
15 | test("Database.QueryLocator variable declaration") {
16 | typeDeclaration("""public class Dummy {{
17 | Database.QueryLocator result;
18 | System.Iterator < SObject > iteratorResult = result.iterator();
19 | }}""")
20 | assert(!hasIssues)
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/apexlink/src/test/scala/com/nawforce/apexlink/parsers/CodeParserTest.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2017 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.apexlink.parsers
15 |
16 | import com.nawforce.apexlink.api.ServerOps
17 | import com.nawforce.apexlink.{FileSystemHelper, TestHelper}
18 | import com.nawforce.pkgforce.path.PathLike
19 | import com.nawforce.runtime.parsers.{CodeParser, SourceData}
20 | import com.nawforce.runtime.platform.Path
21 | import org.scalatest.BeforeAndAfter
22 | import org.scalatest.funsuite.AnyFunSuite
23 |
24 | class CodeParserTest extends AnyFunSuite with BeforeAndAfter with TestHelper {
25 |
26 | before {
27 | ServerOps.setAutoFlush(false)
28 | }
29 |
30 | after {
31 | ServerOps.setAutoFlush(true)
32 | }
33 |
34 | test("Good class") {
35 | val parser = CodeParser(Path("Hello.cls"), SourceData("public class Hello {}"))
36 | val result = parser.parseClass()
37 | assert(result.issues.isEmpty)
38 | }
39 |
40 | test("Broken class") {
41 | val parser = CodeParser(Path("Hello.cls"), SourceData("public class Hello {"))
42 | val result = parser.parseClass()
43 | assert(result.issues.nonEmpty)
44 | }
45 |
46 | test("UTF-8 class") {
47 | FileSystemHelper.run(
48 | Map("Dummy.cls" -> "public class Dummy {{String a = 'Kimi Räikkönen';}}")
49 | ) { root: PathLike =>
50 | val org = createOrg(root)
51 | assert(org.issues.isEmpty)
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/pkgforce/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .bsp/
3 | .metals/
4 | .vscode
5 | **/target/
6 | **/node_modules/
7 | js/npm/package-lock.json
8 | js/npm/pkgforce-fastopt.js
9 | js/npm/pkgforce-fastopt.js.map
10 | js/npm/pkgforce-opt.js
11 | js/npm/pkgforce-opt.js.map
12 | js/npm/lib/
13 |
14 |
--------------------------------------------------------------------------------
/pkgforce/.scalafmt.conf:
--------------------------------------------------------------------------------
1 | version = 2.6.3
2 | continuationIndent.defnSite = 2
3 | optIn.configStyleArguments = false
4 | align.preset = more
5 | maxColumn = 100
6 |
--------------------------------------------------------------------------------
/pkgforce/README.md:
--------------------------------------------------------------------------------
1 | ## pkgforce
2 |
3 | Provides utility functions for handling collections of Salesforce metadata. The library is implemented in Scala in a
4 | style that allows it to be compiled for either use on both JVM or node.
5 |
6 | ### NPM API
7 |
8 | The library is mostly written in Scala to support dual building for Java & Node. This model works well when you are
9 | also using Scala and is usable from Java but is more awkward for Node clients. To overcome this a small part of the
10 | library for resolving type names to paths is exposed in a Node friendly NPM module.
11 |
12 | To use this, first create a workspace:
13 |
14 | const workspace = Workspaces.get("mydirectory") // Will throw on errors
15 |
16 | Call findType on the workspace:
17 |
18 | const fooPath = workspace.findType("ns001.Foo") // Returns null if type is unknown
19 |
20 | A workspace here is simply the directory containing Salesforce metadata, typically it's the directory in which
21 | sfdx-project.json resides.
22 |
23 | ### Java Distribution via Maven
24 |
25 | To use in a JVM project
26 |
27 |
28 | com.github.nawforce
29 | pkgforce
30 | 2.3.7/version>
31 |
32 |
33 | ### Scala/Scala.js
34 |
35 | For scala.js:
36 |
37 | libraryDependencies += "com.github.nawforce" %%% "pkgforce" % "2.3.7"
38 |
39 | For scala:
40 |
41 | libraryDependencies += "com.github.nawforce" % "pkgforce" % "2.3.7"
42 |
43 | ### Building
44 |
45 | The dual build (Java & JS) is handled by [sbt](https://www.scala-sbt.org/):
46 |
47 | sbt build
48 |
49 | To run tests:
50 |
51 | sbt test
52 |
53 | A maven pom.xml is also provided to aid compatibility with IntelliJ. See top level README.md for details on use.
54 |
--------------------------------------------------------------------------------
/pkgforce/js/npm/.gitignore:
--------------------------------------------------------------------------------
1 | src/pkgforce.js
2 | README.md
3 |
--------------------------------------------------------------------------------
/pkgforce/js/npm/.npmignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nawforce/apex-link/7688adcb7a2d7f8aa28d0618ffb2a3aa81151858/pkgforce/js/npm/.npmignore
--------------------------------------------------------------------------------
/pkgforce/js/npm/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Debug Jest Tests",
9 | "type": "node",
10 | "request": "launch",
11 | "runtimeArgs": [
12 | "--inspect-brk",
13 | "${workspaceRoot}/node_modules/.bin/jest",
14 | "--runInBand"
15 | ],
16 | "console": "integratedTerminal",
17 | "internalConsoleOptions": "neverOpen"
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/pkgforce/js/npm/jestconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "transform": {
3 | "^.+\\.tsx?$": "ts-jest"
4 | },
5 | "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
6 | "moduleFileExtensions": [
7 | "ts",
8 | "tsx",
9 | "js",
10 | "jsx",
11 | "json",
12 | "node"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/pkgforce/js/npm/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pkgforce",
3 | "version": "2.3.7",
4 | "description": "Salesforce Metadata Management Utility Library",
5 | "publisher": "KevinJones",
6 | "repository": "nawforce/pkgforce",
7 | "author": "Kevin Jones (https://github.com/nawforce)",
8 | "license": "BSD-3-Clause",
9 | "bugs": "https://github.com/nawforce/pkgforce/issues",
10 | "icon": "logo.png",
11 | "scripts": {
12 | "build": "tsc",
13 | "test": "jest --config jestconfig.json lib"
14 | },
15 | "main": "lib/pkgforce.js",
16 | "typings": "src/pkgforce.d.ts",
17 | "files": [
18 | "src/pkgforce.d.ts"
19 | ],
20 | "dependencies": {
21 | "antlr4ts": "0.5.0-alpha.4",
22 | "@apexdevtools/apex-parser": "3.0.0",
23 | "vf-parser": "1.0.0",
24 | "@xmldom/xmldom": "0.7.5"
25 | },
26 | "devDependencies": {
27 | "@types/jest": "^27.0.2",
28 | "fs-monkey": "0.3.3",
29 | "jest": "^27.2.5",
30 | "memfs": "3.2.0",
31 | "ts-jest": "^27.0.5",
32 | "typescript": "^4.4.4"
33 | },
34 | "engines": {
35 | "node": ">=8.0.0"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/pkgforce/js/npm/src/__tests__/WorkspaceTest.ts:
--------------------------------------------------------------------------------
1 | import {Workspaces} from "../pkgforce";
2 | import {vol} from "memfs";
3 | import {patchFs} from "fs-monkey";
4 |
5 | test("Bad directory", () => {
6 | try {
7 | Workspaces.get("foo");
8 | expect(true).toBe(false);
9 | } catch (err) {
10 | expect(err.message).toMatch(/.*No directory at .*/);
11 | }
12 | });
13 |
14 | test("Empty directory", () => {
15 | vol.fromJSON({"/pkg1/README.md": ""});
16 | const unpatch = patchFs(vol);
17 | try {
18 | const workspace = Workspaces.get("/pkg1");
19 | expect(workspace).toBeDefined();
20 | expect(workspace.findType("Foo")).toBeNull;
21 | } finally {
22 | unpatch();
23 | }
24 | });
25 |
26 | test("MDAPI Class", () => {
27 | vol.fromJSON({"/pkg2/classes/Foo.cls": ""});
28 | const unpatch = patchFs(vol);
29 | try {
30 | const workspace = Workspaces.get("/pkg2");
31 | expect(workspace).toBeDefined();
32 | expect(workspace.findType("Foo")).toEqual(["/pkg2/classes/Foo.cls"]);
33 | } finally {
34 | unpatch();
35 | }
36 | });
37 |
38 | test("SFDX Bad Project file", () => {
39 | vol.fromJSON({"/pkg3/sfdx-project.json": ""});
40 | const unpatch = patchFs(vol);
41 | try {
42 | const workspace = Workspaces.get("/pkg3");
43 | expect(true).toBe(false);
44 | } catch (err) {
45 | expect(err.message).toMatch(
46 | "/pkg3/sfdx-project.json line 1 Error Failed to parse - ujson.IncompleteParseException: exhausted input"
47 | );
48 | } finally {
49 | unpatch();
50 | }
51 | });
52 |
53 | test("SFDX without namespace", () => {
54 | vol.fromJSON({
55 | "/pkg4/sfdx-project.json": '{ "packageDirectories": [{"path": "classes"}]}',
56 | "/pkg4/classes/Foo.cls": "",
57 | });
58 | const unpatch = patchFs(vol);
59 | try {
60 | const workspace = Workspaces.get("/pkg4");
61 | expect(workspace).toBeDefined();
62 | expect(workspace.findType("Foo")).toEqual(["/pkg4/classes/Foo.cls"]);
63 | } finally {
64 | unpatch();
65 | }
66 | });
67 |
68 | test("SFDX with namespace", () => {
69 | vol.fromJSON({
70 | "/pkg5/sfdx-project.json": '{ "packageDirectories": [{"path": "classes"}], "namespace": "ns001"}',
71 | "/pkg5/classes/Foo.cls": "",
72 | });
73 | const unpatch = patchFs(vol);
74 | try {
75 | const workspace = Workspaces.get("/pkg5");
76 | expect(workspace).toBeDefined();
77 | expect(workspace.findType("ns001.Foo")).toEqual(["/pkg5/classes/Foo.cls"]);
78 | } finally {
79 | unpatch();
80 | }
81 | });
82 |
--------------------------------------------------------------------------------
/pkgforce/js/npm/src/pkgforce.d.ts:
--------------------------------------------------------------------------------
1 | export declare class WorkspaceException {
2 | message: string;
3 | }
4 |
5 | export declare class Workspace {
6 | findType(name: string): string | null;
7 | }
8 |
9 | export declare class Workspaces {
10 | static get(path: string): Workspace;
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/pkgforce/js/npm/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2015",
4 | "module": "commonjs",
5 | "sourceMap": true,
6 | "declaration": false,
7 | "rootDir": "src",
8 | "outDir": "lib",
9 | "allowJs": true,
10 | "esModuleInterop": true
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/apexparser/ApexLexer.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.apexparser
15 |
16 | import scala.scalajs.js
17 | import scala.scalajs.js.annotation.JSImport
18 |
19 | @js.native
20 | @JSImport("@apexdevtools/apex-parser", "ApexLexer")
21 | class ApexLexer(stream: CaseInsensitiveInputStream) extends js.Object {}
22 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/apexparser/CaseInsensitiveInputStream.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.apexparser
15 |
16 | import com.nawforce.runtime.parsers.antlr.CharStream
17 |
18 | import scala.scalajs.js
19 | import scala.scalajs.js.annotation.JSImport
20 |
21 | @js.native
22 | @JSImport("@apexdevtools/apex-parser", "CaseInsensitiveInputStream")
23 | class CaseInsensitiveInputStream(src: CharStream) extends CharStream {}
24 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/pkgforce/api/Issue.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.api
15 |
16 | trait Issue {
17 | /* The file path where the issue was found */
18 | def filePath(): String
19 |
20 | /* The location within the file */
21 | def fileLocation(): IssueLocation
22 |
23 | /* The category of the issue, one of "Syntax", "Error", "Missing", "Warning" or "Unused" */
24 | def category(): String
25 |
26 | /* The issue message */
27 | def message(): String
28 |
29 | /* Is this considered an error issue, rather than a warning */
30 | def isError(): java.lang.Boolean
31 |
32 | /* Format as String, filePath is omitted to avoid duplicating over multiple Issues */
33 | def asString: String = category() + ": " + fileLocation().displayPosition + ": " + message()
34 |
35 | override def toString: String = filePath() + ": " + asString
36 | }
37 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/pkgforce/api/IssueLocation.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.api
15 |
16 | trait IssueLocation {
17 | def startLineNumber(): Int
18 | def startCharOffset(): Int
19 | def endLineNumber(): Int
20 | def endCharOffset(): Int
21 |
22 | def displayPosition: String = {
23 | if (
24 | startLineNumber() == 1 && endLineNumber() == Int.MaxValue && startCharOffset() == 0 && endCharOffset() == 0
25 | ) {
26 | s"line 1"
27 | } else if (startLineNumber() == endLineNumber()) {
28 | if (startCharOffset() == 0 && endCharOffset() == 0)
29 | s"line ${startLineNumber()}"
30 | else if (startCharOffset() == endCharOffset())
31 | s"line ${startLineNumber()} at ${startCharOffset()}"
32 | else
33 | s"line ${startLineNumber()} at ${startCharOffset()}-${endCharOffset()}"
34 | } else {
35 | if (startCharOffset() == 0 && endCharOffset() == 0)
36 | s"line ${startLineNumber()} to ${endLineNumber()}"
37 | else
38 | s"line ${startLineNumber()}:${startCharOffset()} to ${endLineNumber()}:${endCharOffset()}"
39 | }
40 | }
41 |
42 | def contains(line: Int, offset: Int): Boolean = {
43 | !(line < startLineNumber() || line > endLineNumber() ||
44 | (line == startLineNumber() && offset < startCharOffset()) ||
45 | (line == endLineNumber() && offset > endCharOffset()))
46 | }
47 |
48 | def contains(other: IssueLocation): Boolean = {
49 | contains(other.startLineNumber(), other.startCharOffset()) &&
50 | contains(other.endLineNumber(), other.endCharOffset())
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/pkgforce/api/Workspaces.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.api
15 |
16 | import com.nawforce.pkgforce.names.DotName
17 | import com.nawforce.pkgforce.path.PathFactory
18 | import com.nawforce.pkgforce.workspace.{Workspace => SWorkspace}
19 |
20 | import scala.collection.mutable
21 | import scala.scalajs.js
22 | import scala.scalajs.js.JSConverters._
23 | import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
24 |
25 | @JSExportTopLevel("WorkspaceException")
26 | class WorkspaceException(val message: String) extends Exception(message)
27 |
28 | @JSExportTopLevel("Workspace")
29 | class Workspace(val workspace: SWorkspace) {
30 |
31 | @JSExport
32 | def findType(name: String): js.Array[String] = {
33 | workspace.get(DotName(name).asTypeName()).map(_.path.toString).toJSArray
34 | }
35 | }
36 |
37 | @JSExportTopLevel("Workspaces")
38 | object Workspaces {
39 | private val workspaces = new mutable.HashMap[String, Workspace]()
40 |
41 | @JSExport
42 | def get(wsPath: String): Workspace = {
43 |
44 | val ws = workspaces.get(wsPath)
45 | if (ws.nonEmpty)
46 | return ws.get
47 |
48 | val issuesAndWorkspace = SWorkspace(PathFactory(wsPath))
49 | if (issuesAndWorkspace.issues.nonEmpty) {
50 | throw new WorkspaceException(issuesAndWorkspace.issues.head.asString)
51 | }
52 |
53 | issuesAndWorkspace.value
54 | .map(workspace => {
55 | val jsWorkspace = new Workspace(workspace)
56 | workspaces.put(wsPath, new Workspace(workspace))
57 | jsWorkspace
58 | })
59 | .orNull
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/package.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce
15 |
16 | import java.nio.charset.StandardCharsets
17 |
18 | /** Platform specific handling for Node execution.
19 | *
20 | * Contains a number of abstractions for handling the differences between JVM & Node execution. This is just the JVM
21 | * implementation, the node version of the same abstraction is not in this project. See [[com.nawforce.pkgforce]] for
22 | * the analysis code.
23 | */
24 | package object runtime {
25 | type SourceBlob = Array[Byte]
26 |
27 | object SourceBlob {
28 | def apply(value: String): SourceBlob = {
29 | value.getBytes(StandardCharsets.UTF_8)
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/parsers/CollectingErrorListener.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.parsers
15 |
16 | import com.nawforce.pkgforce.diagnostics.{Diagnostic, Issue, SYNTAX_CATEGORY}
17 | import com.nawforce.pkgforce.path.{Location, PathLike}
18 |
19 | import scala.collection.compat.immutable.ArraySeq
20 | import scala.collection.mutable
21 | import scala.scalajs.js
22 |
23 | class CollectingErrorListener(path: PathLike) extends js.Object {
24 | var _issues: mutable.ArrayBuffer[Issue] = _
25 |
26 | def syntaxError(
27 | recognizer: Any,
28 | offendingSymbol: Any,
29 | line: Int,
30 | charPositionInLine: Int,
31 | msg: String,
32 | e: Any
33 | ): Unit = {
34 | if (_issues == null)
35 | _issues = new mutable.ArrayBuffer[Issue]()
36 |
37 | _issues.addOne(
38 | new Issue(path, Diagnostic(SYNTAX_CATEGORY, Location(line, charPositionInLine), msg))
39 | )
40 | }
41 |
42 | def issues: ArraySeq[Issue] = {
43 | if (_issues != null)
44 | ArraySeq.unsafeWrapArray(_issues.toArray)
45 | else
46 | Issue.emptyArray
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/parsers/VFLexer.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.parsers
15 |
16 | import com.nawforce.runtime.parsers.antlr.CharStream
17 |
18 | import scala.scalajs.js
19 | import scala.scalajs.js.annotation.JSImport
20 |
21 | @js.native
22 | @JSImport("vf-parser", "VFLexer")
23 | class VFLexer(stream: CharStream) extends js.Object {
24 | def removeErrorListeners(): Unit = js.native
25 | def addErrorListener(listener: CollectingErrorListener): Unit = js.native
26 | }
27 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/parsers/antlr/ANTLRInputStream.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.parsers.antlr
15 |
16 | import scala.scalajs.js
17 | import scala.scalajs.js.annotation.JSImport
18 |
19 | @js.native
20 | @JSImport("antlr4ts", "ANTLRInputStream")
21 | class ANTLRInputStream extends js.Object {
22 | def getText(interval: Interval): String = js.native
23 | }
24 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/parsers/antlr/AbstractParseTreeVisitor.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.parsers.antlr
15 |
16 | import scala.scalajs.js
17 | import scala.scalajs.js.annotation.JSImport
18 |
19 | @js.native
20 | @JSImport("antlr4ts/tree/AbstractParseTreeVisitor", "AbstractParseTreeVisitor")
21 | class AbstractParseTreeVisitor[Result] extends js.Object {
22 | def visit(tree: ParseTree): Result = js.native
23 |
24 | def visitChildren(node: RuleNode): Result = js.native
25 | def visitTerminal(node: TerminalNode): Result = js.native
26 | def visitErrorNode(node: ErrorNode): Result = js.native
27 | protected def defaultResult(): Result = js.native
28 | protected def aggregateResult(aggregate: Result, nextResult: Result): Result = js.native
29 | protected def shouldVisitNextChild(node: RuleNode, currentResult: Result): Boolean = js.native
30 | }
31 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/parsers/antlr/ApexParserVisitor.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.parsers.antlr
15 |
16 | import com.nawforce.apexparser.ApexParser._
17 |
18 | import scala.scalajs.js
19 |
20 | trait ApexParserVisitor[Result] extends js.Object {
21 | val visitCompilationUnit: js.UndefOr[js.Function1[CompilationUnitContext, Result]] = js.undefined
22 |
23 | val visitTriggerUnit: js.UndefOr[js.Function1[TriggerUnitContext, Result]] = js.undefined
24 |
25 | val visitTypeDeclaration: js.UndefOr[js.Function1[TypeDeclarationContext, Result]] = js.undefined
26 |
27 | val visitClassDeclaration: js.UndefOr[js.Function1[ClassDeclarationContext, Result]] =
28 | js.undefined
29 | val visitInterfaceDeclaration: js.UndefOr[js.Function1[InterfaceDeclarationContext, Result]] =
30 | js.undefined
31 | val visitEnumDeclaration: js.UndefOr[js.Function1[EnumDeclarationContext, Result]] = js.undefined
32 |
33 | val visitFieldDeclaration: js.UndefOr[js.Function1[FieldDeclarationContext, Result]] =
34 | js.undefined
35 | val visitPropertyDeclaration: js.UndefOr[js.Function1[PropertyDeclarationContext, Result]] =
36 | js.undefined
37 | val visitConstructorDeclaration: js.UndefOr[js.Function1[ConstructorDeclarationContext, Result]] =
38 | js.undefined
39 | val visitMethodDeclaration: js.UndefOr[js.Function1[MethodDeclarationContext, Result]] =
40 | js.undefined
41 | val visitInterfaceMethodDeclaration
42 | : js.UndefOr[js.Function1[InterfaceMethodDeclarationContext, Result]] = js.undefined
43 | val visitEnumConstants: js.UndefOr[js.Function1[EnumConstantsContext, Result]] = js.undefined
44 | }
45 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/parsers/antlr/BufferedTokenStream.scala:
--------------------------------------------------------------------------------
1 | package com.nawforce.runtime.parsers.antlr
2 |
3 | import scala.scalajs.js
4 | import scala.scalajs.js.annotation.JSImport
5 |
6 | @js.native
7 | @JSImport("antlr4ts", "BufferedTokenStream")
8 | class BufferedTokenStream extends js.Object {
9 | def getHiddenTokensToRight(tokenIndex: Int): js.Array[Token] = js.native
10 | def getHiddenTokensToLeft(tokenIndex: Int): js.Array[Token] = js.native
11 | }
12 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/parsers/antlr/CharStream.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.parsers.antlr
15 |
16 | import scala.scalajs.js
17 | import scala.scalajs.js.annotation.JSImport
18 |
19 | @js.native
20 | @JSImport("antlr4ts/CharStream", "CharStream")
21 | class CharStream extends js.Object {}
22 |
23 | @js.native
24 | @JSImport("antlr4ts/CharStreams", "CharStreams")
25 | object CharStreams extends js.Object {
26 | def fromString(s: String): CharStream = js.native
27 | def fromString(s: String, sourceName: String): CharStream = js.native
28 | }
29 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/parsers/antlr/CommonTokenStream.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.parsers.antlr
15 |
16 | import scala.scalajs.js
17 | import scala.scalajs.js.annotation.JSImport
18 |
19 | @js.native
20 | @JSImport("antlr4ts", "CommonTokenStream")
21 | class CommonTokenStream(lexer: js.Any) extends BufferedTokenStream {
22 | def fill(): Unit = js.native
23 | }
24 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/parsers/antlr/ErrorNode.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.parsers.antlr
15 |
16 | import scala.scalajs.js
17 |
18 | @js.native
19 | trait ErrorNode extends TerminalNode
20 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/parsers/antlr/Interval.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.parsers.antlr
15 |
16 | import scala.scalajs.js
17 | import scala.scalajs.js.annotation.JSImport
18 |
19 | @js.native
20 | @JSImport("antlr4ts/misc/Interval", "Interval")
21 | class Interval(a: Int, b: Int) extends js.Object
22 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/parsers/antlr/ParseTree.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.parsers.antlr
15 |
16 | import scala.scalajs.js
17 |
18 | @js.native
19 | trait ParseTree extends js.Object {
20 | val text: String = js.native
21 | }
22 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/parsers/antlr/ParserRuleContext.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.parsers.antlr
15 |
16 | import scala.scalajs.js
17 | import scala.scalajs.js.annotation.JSImport
18 |
19 | @js.native
20 | @JSImport("antlr4ts", "ParserRuleContext")
21 | class ParserRuleContext extends RuleContext {
22 | val start: Token = js.native
23 | val stop: Token = js.native
24 |
25 | def parent: ParserRuleContext = js.native
26 | val childCount: Int = js.native
27 | def getChild(i: Int): ParseTree = js.native
28 | }
29 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/parsers/antlr/RuleContext.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.parsers.antlr
15 |
16 | import scala.scalajs.js
17 |
18 | @js.native
19 | trait RuleContext extends RuleNode
20 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/parsers/antlr/RuleNode.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.parsers.antlr
15 |
16 | import scala.scalajs.js
17 |
18 | @js.native
19 | trait RuleNode extends ParseTree
20 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/parsers/antlr/TerminalNode.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.parsers.antlr
15 |
16 | import scala.scalajs.js
17 | import scala.scalajs.js.annotation.JSImport
18 |
19 | @js.native
20 | @JSImport("antlr4ts/tree/TerminalNode", "TerminalNode")
21 | class TerminalNode extends ParseTree {}
22 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/parsers/antlr/Token.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.parsers.antlr
15 |
16 | import com.nawforce.apexparser.CaseInsensitiveInputStream
17 |
18 | import scala.scalajs.js
19 | import scala.scalajs.js.annotation.JSImport
20 |
21 | @js.native
22 | @JSImport("antlr4ts", "Token")
23 | class Token extends js.Object {
24 | val text: String = js.native
25 | val line: Int = js.native
26 | val charPositionInLine: Int = js.native
27 | val inputStream: CaseInsensitiveInputStream = js.native
28 | val startIndex: Int = js.native
29 | val stopIndex: Int = js.native
30 | }
31 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/platform/Environment.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.runtime.platform
16 |
17 | import com.nawforce.pkgforce.path.PathLike
18 | import io.scalajs.nodejs.process.Process
19 |
20 | import scala.scalajs.js
21 | import scala.scalajs.js.annotation.JSImport
22 |
23 | object Environment {
24 | private val CACHE_DIR: String = ".apexlink_cache"
25 | private var cacheDirOverride: Option[Option[PathLike]] = None
26 |
27 | def gc(): Unit = {
28 | // Not implemented
29 | }
30 |
31 | def homedir: Option[Path] = {
32 | Option(OSExtra.homedir()).filter(_.nonEmpty).map(Path(_))
33 | }
34 |
35 | def cacheDir: Option[PathLike] = {
36 | if (cacheDirOverride.nonEmpty)
37 | return cacheDirOverride.get
38 |
39 | try {
40 | Process
41 | .env("APEXLINK_CACHE_DIR")
42 | .toOption
43 | .filter(_.nonEmpty)
44 | .map(Path(_))
45 | .orElse(Environment.homedir.map(_.join(CACHE_DIR)))
46 | } catch {
47 | case _: Throwable => None
48 | }
49 | }
50 |
51 | // Only for test usage
52 | def setCacheDirOverride(value: Option[Option[PathLike]]): Unit = {
53 | cacheDirOverride = value
54 | }
55 |
56 | def isWindows: Boolean = {
57 | // It's win32 even on Win64
58 | Process.platform == "win32"
59 | }
60 |
61 | }
62 |
63 | @js.native
64 | trait OSExtra extends js.Object {
65 | def homedir(): String = js.native
66 | }
67 |
68 | @js.native
69 | @JSImport("os", JSImport.Namespace)
70 | object OSExtra extends OSExtra
71 |
--------------------------------------------------------------------------------
/pkgforce/js/src/main/scala/com/nawforce/runtime/xml/XMLDom.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.xml
15 |
16 | import scala.scalajs.js
17 | import scala.scalajs.js.annotation._
18 |
19 | @js.native
20 | trait NodeList extends js.Object {
21 | val length: Int = js.native
22 | def item(at: Int): Node = js.native
23 | }
24 |
25 | @js.native
26 | trait Node extends js.Object {
27 | val lineNumber: Int = js.native
28 | val columnNumber: Int = js.native
29 |
30 | val nodeType: Int = js.native
31 | val nodeName: String = js.native
32 |
33 | val namespaceURI: String = js.native
34 | val localName: String = js.native
35 |
36 | val childNodes: NodeList = js.native
37 | }
38 |
39 | object Node {
40 | val ELEMENT_NODE = 1
41 | val ATTRIBUTE_NODE = 2
42 | val TEXT_NODE = 3
43 | val CDATA_SECTION_NODE = 4
44 | val ENTITY_REFERENCE_NODE = 5
45 | val ENTITY_NODE = 6
46 | val PROCESSING_INSTRUCTION_NODE = 7
47 | val COMMENT_NODE = 8
48 | val DOCUMENT_NODE = 9
49 | val DOCUMENT_TYPE_NODE = 10
50 | val DOCUMENT_FRAGMENT_NODE = 11
51 | val NOTATION_NODE = 12
52 | }
53 |
54 | @js.native
55 | trait Element extends Node {}
56 |
57 | @js.native
58 | trait CharacterData extends Node {
59 | val data: String = js.native
60 | }
61 |
62 | @js.native
63 | trait Text extends CharacterData {}
64 |
65 | @js.native
66 | trait Document extends js.Object {
67 | val documentElement: Element = js.native
68 | }
69 |
70 | @js.native
71 | @JSImport("@xmldom/xmldom", "DOMParser")
72 | class DOMParser(options: js.Dynamic) extends js.Object {
73 | def parseFromString(xmlSource: String, mimeType: String): Document = js.native
74 | }
75 |
--------------------------------------------------------------------------------
/pkgforce/js/src/test/scala/com/nawforce/runtime/imports/FSMonkey.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.imports
15 |
16 | import scala.scalajs.js
17 | import scala.scalajs.js.annotation.JSImport
18 |
19 | @js.native
20 | trait FSMonkey extends js.Object {
21 | def patchRequire(vol: js.Object): Unit = js.native
22 | def patchFs(vol: js.Object): js.Function0[Unit] = js.native
23 | }
24 |
25 | @js.native
26 | @JSImport("fs-monkey", JSImport.Namespace)
27 | object FSMonkey extends FSMonkey
28 |
--------------------------------------------------------------------------------
/pkgforce/js/src/test/scala/com/nawforce/runtime/imports/Memfs.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.imports
15 |
16 | import io.scalajs.nodejs.fs.Fs
17 |
18 | import scala.scalajs.js
19 | import scala.scalajs.js.annotation.JSImport
20 |
21 | @js.native
22 | trait Volume extends Fs {
23 | def fromJSON(json: js.Dynamic, cwd: String = ""): Unit = js.native
24 | def toJSON(): js.Object = js.native
25 | def reset(): Unit = js.native
26 | }
27 |
28 | @js.native
29 | trait Memfs extends js.Object {
30 | val vol: Volume = js.native
31 | val fs: js.Object = js.native
32 | }
33 |
34 | @js.native
35 | @JSImport("memfs", JSImport.Namespace)
36 | object Memfs extends Memfs
37 |
--------------------------------------------------------------------------------
/pkgforce/jvm/src/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Class-Path:
3 | antlr4-runtime-4.8-1.jar
4 | apex-parser-3.0.0.jar
5 | geny_2.13-0.6.2.jar
6 | scala-collection-compat_2.13-2.1.4.jar
7 | scala-json-rpc-upickle-json-serializer_2.13-1.0.1.jar
8 | scala-json-rpc_2.13-1.0.1.jar
9 | scala-library-2.13.3.jar
10 | scala-reflect-2.13.3.jar
11 | scala-xml_2.13-1.3.0.jar
12 | ujson_2.13-1.2.0.jar
13 | upack_2.13-1.2.0.jar
14 | upickle-core_2.13-1.2.0.jar
15 | upickle-implicits_2.13-1.2.0.jar
16 | upickle_2.13-1.2.0.jar
17 |
--------------------------------------------------------------------------------
/pkgforce/jvm/src/main/java/com/nawforce/pkgforce/api/Issue.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.pkgforce.api;
16 |
17 | public abstract class Issue {
18 | /* The file path where the issue was found */
19 | public abstract String filePath();
20 |
21 | /* The location within the file */
22 | public abstract IssueLocation fileLocation();
23 |
24 | /* The category of the issue, one of "Syntax", "Error", "Missing", "Warning" or "Unused" */
25 | public abstract String category();
26 |
27 | /* Is this considered an error issue, rather than a warning */
28 | public abstract Boolean isError();
29 |
30 | /* The issue message */
31 | public abstract String message();
32 |
33 | /* Format as String, filePath is omitted to avoid duplicating over multiple Issues */
34 | public String asString() {
35 | return category() + ": " + fileLocation().displayPosition() + ": " + message();
36 | }
37 |
38 | @Override
39 | public String toString() {
40 | return filePath() + ": " + asString();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/pkgforce/jvm/src/main/java/com/nawforce/pkgforce/api/IssueLocation.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.api;
15 |
16 | public abstract class IssueLocation {
17 | public abstract int startLineNumber();
18 | public abstract int startCharOffset();
19 | public abstract int endLineNumber();
20 | public abstract int endCharOffset();
21 |
22 | public String displayPosition() {
23 | if (startLineNumber() == 1 && endLineNumber() == Integer.MAX_VALUE && startCharOffset() == 0 && endCharOffset() == 0) {
24 | return "line 1";
25 | }
26 | if (startLineNumber() == endLineNumber()) {
27 | if (startCharOffset() == 0 && endCharOffset() == 0)
28 | return "line " + startLineNumber();
29 | else if (startCharOffset() == endCharOffset())
30 | return "line " + startLineNumber() + " at " + startCharOffset();
31 | else
32 | return "line " + startLineNumber() + " at " + startCharOffset() + "-" + endCharOffset();
33 | } else {
34 | if (startCharOffset() == 0 && endCharOffset() == 0)
35 | return "line " + startLineNumber() + " to " + endLineNumber();
36 | else
37 | return "line " + startLineNumber() + ":" + startCharOffset() + " to " + endLineNumber() + ":" + endCharOffset();
38 | }
39 | }
40 |
41 | public boolean contains(int line, int offset) {
42 | return !(line < startLineNumber() || line > endLineNumber() ||
43 | (line == startLineNumber() && offset < startCharOffset()) ||
44 | (line == endLineNumber() && offset > endCharOffset()));
45 | }
46 |
47 | public boolean contains(IssueLocation other) {
48 | return contains(other.startLineNumber(), other.startCharOffset()) &&
49 | contains(other.endLineNumber(), other.endCharOffset());
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/pkgforce/jvm/src/main/java/com/nawforce/runtime/parsers/VFParserVisitor.java:
--------------------------------------------------------------------------------
1 | // Generated from /Users/kevin/Projects/pkgforce/jvm/src/main/antlr/com/nawforce/parsers/VFParser.g4 by ANTLR 4.8
2 | package com.nawforce.runtime.parsers;
3 | import org.antlr.v4.runtime.tree.ParseTreeVisitor;
4 |
5 | /**
6 | * This interface defines a complete generic visitor for a parse tree produced
7 | * by {@link VFParser}.
8 | *
9 | * @param The return type of the visit operation. Use {@link Void} for
10 | * operations with no return type.
11 | */
12 | public interface VFParserVisitor extends ParseTreeVisitor {
13 | /**
14 | * Visit a parse tree produced by {@link VFParser#vfUnit}.
15 | * @param ctx the parse tree
16 | * @return the visitor result
17 | */
18 | T visitVfUnit(VFParser.VfUnitContext ctx);
19 | /**
20 | * Visit a parse tree produced by {@link VFParser#element}.
21 | * @param ctx the parse tree
22 | * @return the visitor result
23 | */
24 | T visitElement(VFParser.ElementContext ctx);
25 | /**
26 | * Visit a parse tree produced by {@link VFParser#attribute}.
27 | * @param ctx the parse tree
28 | * @return the visitor result
29 | */
30 | T visitAttribute(VFParser.AttributeContext ctx);
31 | /**
32 | * Visit a parse tree produced by {@link VFParser#attributeName}.
33 | * @param ctx the parse tree
34 | * @return the visitor result
35 | */
36 | T visitAttributeName(VFParser.AttributeNameContext ctx);
37 | /**
38 | * Visit a parse tree produced by {@link VFParser#attributeValues}.
39 | * @param ctx the parse tree
40 | * @return the visitor result
41 | */
42 | T visitAttributeValues(VFParser.AttributeValuesContext ctx);
43 | /**
44 | * Visit a parse tree produced by {@link VFParser#content}.
45 | * @param ctx the parse tree
46 | * @return the visitor result
47 | */
48 | T visitContent(VFParser.ContentContext ctx);
49 | /**
50 | * Visit a parse tree produced by {@link VFParser#chardata}.
51 | * @param ctx the parse tree
52 | * @return the visitor result
53 | */
54 | T visitChardata(VFParser.ChardataContext ctx);
55 | /**
56 | * Visit a parse tree produced by {@link VFParser#processingInstruction}.
57 | * @param ctx the parse tree
58 | * @return the visitor result
59 | */
60 | T visitProcessingInstruction(VFParser.ProcessingInstructionContext ctx);
61 | /**
62 | * Visit a parse tree produced by {@link VFParser#scriptChardata}.
63 | * @param ctx the parse tree
64 | * @return the visitor result
65 | */
66 | T visitScriptChardata(VFParser.ScriptChardataContext ctx);
67 | }
--------------------------------------------------------------------------------
/pkgforce/jvm/src/main/scala/com/nawforce/runtime/cmds/Scan.scala:
--------------------------------------------------------------------------------
1 | package com.nawforce.runtime.cmds
2 |
3 | import com.nawforce.pkgforce.path.PathFactory
4 | import com.nawforce.pkgforce.workspace.Workspace
5 |
6 | object Scan {
7 |
8 | def main(args: Array[String]): Unit = {
9 | if (args.length == 0) {
10 | println("Missing argument, expecting directory to scan")
11 | System.exit(-1)
12 | }
13 |
14 | if (args.length > 1) {
15 | println("Too many arguments, expecting directory to scan")
16 | System.exit(-1)
17 | }
18 |
19 | //Thread.sleep(30*1000)
20 |
21 | val start = System.currentTimeMillis()
22 | val path = PathFactory(args(0))
23 | val issuesAndWs = Workspace(path)
24 | issuesAndWs.issues.foreach(issue => println(issue.asString))
25 | val scanned = System.currentTimeMillis()
26 | println(
27 | issuesAndWs.value
28 | .map(ws => {
29 | val eventCount = ws.events.size
30 | val events = System.currentTimeMillis()
31 | s"Scanned $eventCount events, disk scan took ${scanned - start}ms, event loading took ${events - scanned}ms"
32 | })
33 | .getOrElse({
34 | "Workspace failed to load"
35 | })
36 | )
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/pkgforce/jvm/src/main/scala/com/nawforce/runtime/package.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce
15 |
16 | import java.nio.charset.StandardCharsets
17 |
18 | /** Platform specific handling for JVM execution.
19 | *
20 | * Contains a number of abstractions for handling the differences between JVM & Node execution. This is just the JVM
21 | * implementation, the node version of the same abstraction is not in this project. See [[com.nawforce.pkgforce]] for
22 | * the analysis code.
23 | */
24 | package object runtime {
25 | type SourceBlob = Array[Byte]
26 |
27 | object SourceBlob {
28 | def apply(value: String): SourceBlob = {
29 | value.getBytes(StandardCharsets.UTF_8)
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/pkgforce/jvm/src/main/scala/com/nawforce/runtime/parsers/CollectingErrorListener.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.runtime.parsers
15 |
16 | import com.nawforce.pkgforce.diagnostics.{Diagnostic, Issue, SYNTAX_CATEGORY}
17 | import com.nawforce.pkgforce.path.{Location, PathLike}
18 | import org.antlr.v4.runtime.{BaseErrorListener, RecognitionException, Recognizer}
19 |
20 | import scala.collection.compat.immutable.ArraySeq
21 | import scala.collection.mutable
22 |
23 | class CollectingErrorListener(path: PathLike) extends BaseErrorListener {
24 | var _issues: mutable.ArrayBuffer[Issue] = _
25 |
26 | override def syntaxError(
27 | recognizer: Recognizer[_, _],
28 | offendingSymbol: Any,
29 | line: Int,
30 | charPositionInLine: Int,
31 | msg: String,
32 | e: RecognitionException
33 | ): Unit = {
34 | if (_issues == null)
35 | _issues = new mutable.ArrayBuffer[Issue]()
36 |
37 | _issues.addOne(
38 | new Issue(path, Diagnostic(SYNTAX_CATEGORY, Location(line, charPositionInLine), msg))
39 | )
40 | }
41 |
42 | def issues: ArraySeq[Issue] = {
43 | if (_issues != null)
44 | ArraySeq.unsafeWrapArray(_issues.toArray)
45 | else
46 | Issue.emptyArray
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/pkgforce/jvm/src/main/scala/com/nawforce/runtime/platform/Environment.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.runtime.platform
16 |
17 | import com.nawforce.pkgforce.path.PathLike
18 |
19 | object Environment {
20 | private val CACHE_DIR: String = ".apexlink_cache"
21 | private var cacheDirOverride: Option[Option[PathLike]] = None
22 |
23 | def gc(): Unit = {
24 | System.gc()
25 | }
26 |
27 | def homedir: Option[PathLike] = {
28 | Option(System.getProperty("user.home")).map(Path(_))
29 | }
30 |
31 | def cacheDir: Option[PathLike] = {
32 | if (cacheDirOverride.nonEmpty)
33 | return cacheDirOverride.get
34 |
35 | try {
36 | Option(System.getenv("APEXLINK_CACHE_DIR"))
37 | .filter(_.nonEmpty)
38 | .map(Path(_))
39 | .orElse(Environment.homedir.map(_.join(CACHE_DIR)))
40 | } catch {
41 | case _: Throwable => None
42 | }
43 | }
44 |
45 | // Only for test usage
46 | def setCacheDirOverride(value: Option[Option[PathLike]]): Unit = {
47 | cacheDirOverride = value
48 | }
49 |
50 | def isWindows: Boolean = {
51 | System.getProperty("os.name").contains("Windows")
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/pkgforce/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=1.5.8
2 |
--------------------------------------------------------------------------------
/pkgforce/project/plugins.sbt:
--------------------------------------------------------------------------------
1 | addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.1.1")
2 | addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.0.0")
3 | addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "2.3")
4 | addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2")
5 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/diagnostics/Duplicates.scala:
--------------------------------------------------------------------------------
1 | package com.nawforce.pkgforce.diagnostics
2 |
3 | object Duplicates {
4 |
5 | implicit class IterableOps[A](iterable: Iterable[A]) {
6 |
7 | /** Return duplicates keyed against the first discovered. */
8 | def duplicates[K](f: A => K): Map[A, Iterable[A]] = {
9 | iterable
10 | .groupBy(f)
11 | .collect { case (_, group) if group.size > 1 => group }
12 | .map(group => group.head -> group.tail)
13 | .toMap
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/documents/SourceInfo.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.documents
15 |
16 | import com.nawforce.pkgforce.path.PathLocation
17 | import com.nawforce.runtime.parsers.SourceData
18 |
19 | /** Metadata file information for originating source of something */
20 | final case class SourceInfo(location: PathLocation, hash: Int)
21 |
22 | object SourceInfo {
23 | def apply(location: PathLocation, data: SourceData): SourceInfo = {
24 | new SourceInfo(location, data.hash)
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/memory/Cleanable.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.memory
15 |
16 | import com.nawforce.runtime.platform.Environment
17 |
18 | import scala.collection.mutable
19 |
20 | /** For Caches that can be cleaned/reset as needed to recover memory. */
21 | trait CleanableCache {
22 | Cleanable.register(this)
23 |
24 | def clean(): Unit
25 | }
26 |
27 | /** Manager of cleanable caches. */
28 | object Cleanable {
29 | private val cleanable = mutable.Set[IdentityBox[CleanableCache]]()
30 |
31 | def register(cache: CleanableCache): Unit = {
32 | cleanable.add(new IdentityBox(cache))
33 | }
34 |
35 | def clean(): Unit = {
36 | cleanable.foreach(_.value.clean())
37 | Environment.gc()
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/memory/IdentityBox.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.memory
15 |
16 | /* Value wrapper giving identity equality handling. */
17 | final class IdentityBox[T <: AnyRef](var value: T) {
18 |
19 | override val hashCode: Int = value.hashCode
20 |
21 | override def equals(that: Any): Boolean = {
22 | that match {
23 | case other: IdentityBox[T] => other.value eq this.value
24 | case _ => false
25 | }
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/memory/IdentityEquality.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.memory
15 |
16 | /** Implementation of identity equality, useful as mixin to case classes. */
17 | trait IdentityEquality {
18 | // Identity equals
19 | override def equals(that: Any): Boolean = {
20 | that match {
21 | case other: IdentityEquality => other.eq(this)
22 | case _ => false
23 | }
24 | }
25 |
26 | // Identity hash, may not be unique, storing as val does not appear to improve performance
27 | override def hashCode(): Int = System.identityHashCode(this)
28 | }
29 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/memory/InternCache.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.memory
15 |
16 | import scala.collection.mutable
17 |
18 | /** Cache suitable for interning value. */
19 | class InternCache[T] extends CleanableCache {
20 | private var cache = mutable.HashMap[T, T]()
21 |
22 | def intern(value: T): T = {
23 | cache.getOrElseUpdate(value, value)
24 | }
25 |
26 | def clean(): Unit = {
27 | cache = new mutable.HashMap[T, T]()
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/modifiers/FieldModifiers.scala:
--------------------------------------------------------------------------------
1 | package com.nawforce.pkgforce.modifiers
2 |
3 | import com.nawforce.apexparser.ApexParser.{IdContext, ModifierContext}
4 | import com.nawforce.pkgforce.diagnostics.CodeParserLogger
5 | import com.nawforce.pkgforce.modifiers.ApexModifiers.{
6 | asModifiers,
7 | deduplicateVisibility,
8 | visibilityModifiers
9 | }
10 | import com.nawforce.runtime.parsers.CodeParser
11 |
12 | import scala.collection.compat.immutable.ArraySeq
13 |
14 | object FieldModifiers {
15 | private val FieldModifiers: Set[Modifier] =
16 | visibilityModifiers.toSet ++ Set(
17 | FINAL_MODIFIER,
18 | STATIC_MODIFIER,
19 | TRANSIENT_MODIFIER,
20 | WEBSERVICE_MODIFIER
21 | )
22 |
23 | private val FieldAnnotations: Set[Modifier] =
24 | Set(
25 | AURA_ENABLED_ANNOTATION,
26 | DEPRECATED_ANNOTATION,
27 | INVOCABLE_VARIABLE_ANNOTATION,
28 | TEST_VISIBLE_ANNOTATION,
29 | SUPPRESS_WARNINGS_ANNOTATION_PMD,
30 | SUPPRESS_WARNINGS_ANNOTATION_UNUSED
31 | )
32 |
33 | private val FieldModifiersAndAnnotations: Set[Modifier] = FieldAnnotations ++ FieldModifiers
34 |
35 | private val InnerFieldModifiersAndAnnotations: Set[Modifier] =
36 | FieldModifiersAndAnnotations - STATIC_MODIFIER
37 |
38 | def fieldModifiers(
39 | parser: CodeParser,
40 | modifierContexts: ArraySeq[ModifierContext],
41 | outer: Boolean,
42 | idContext: IdContext
43 | ): ModifierResults = {
44 |
45 | val logger = new CodeParserLogger(parser)
46 | val mods = deduplicateVisibility(
47 | asModifiers(
48 | modifierContexts,
49 | if (outer) FieldModifiersAndAnnotations
50 | else InnerFieldModifiersAndAnnotations,
51 | if (outer) "fields" else "inner class fields",
52 | logger,
53 | idContext
54 | ),
55 | "fields",
56 | logger,
57 | idContext
58 | )
59 |
60 | val results = {
61 | if (mods.intersect(visibilityModifiers).isEmpty && mods.contains(WEBSERVICE_MODIFIER)) {
62 | GLOBAL_MODIFIER +: mods
63 | } else if (
64 | !mods.intersect(visibilityModifiers).contains(GLOBAL_MODIFIER) && mods.contains(
65 | WEBSERVICE_MODIFIER
66 | )
67 | ) {
68 | logger.logError(idContext, s"webservice fields must be global")
69 | GLOBAL_MODIFIER +: mods.diff(visibilityModifiers)
70 | } else if (mods.intersect(visibilityModifiers).isEmpty) {
71 | PRIVATE_MODIFIER +: mods
72 | } else {
73 | mods
74 | }
75 | }
76 | ModifierResults(results, logger.issues).intern
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/modifiers/ModifierResults.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.pkgforce.modifiers
16 |
17 | import com.nawforce.pkgforce.diagnostics.Issue
18 | import com.nawforce.pkgforce.memory.InternCache
19 |
20 | import scala.collection.compat.immutable.ArraySeq
21 |
22 | /** Results from modifier analysis.
23 | *
24 | * Modifiers are examined before the CST is constructed to make things a bit simpler. The results of the analysis
25 | * are returned via this type. Interning is supported to reduce memory use.
26 | */
27 | final case class ModifierResults(modifiers: ArraySeq[Modifier], issues: ArraySeq[Issue]) {
28 |
29 | override val hashCode: Int = modifiers.hashCode()
30 |
31 | def intern: ModifierResults = ModifierResults.intern(this)
32 |
33 | override def equals(that: Any): Boolean = {
34 | that match {
35 | case other: ModifierResults =>
36 | other.canEqual(this) && doesEqual(other)
37 | case _ => false
38 | }
39 | }
40 |
41 | override def canEqual(that: Any): Boolean = that.isInstanceOf[ModifierResults]
42 |
43 | private def doesEqual(other: ModifierResults): Boolean = {
44 | this.modifiers == other.modifiers && this.issues == other.issues
45 | }
46 |
47 | def methodOwnerNature: MethodOwnerNature = {
48 | if (modifiers.contains(ABSTRACT_MODIFIER)) ABSTRACT_METHOD_NATURE
49 | else if (modifiers.contains(VIRTUAL_MODIFIER)) VIRTUAL_METHOD_NATURE
50 | else FINAL_METHOD_NATURE
51 | }
52 |
53 | }
54 |
55 | object ModifierResults extends InternCache[ModifierResults] {
56 | val empty: ModifierResults = ModifierResults(ArraySeq.empty, ArraySeq.empty)
57 | }
58 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/names/DotName.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.names
15 |
16 | /**
17 | * A qualified name with notional 'dot' separators
18 | */
19 | final case class DotName(names: Seq[Name]) {
20 |
21 | val isCompound: Boolean = names.size > 1
22 |
23 | def head: DotName = DotName(Seq(names.head))
24 | def tail: DotName = DotName(names.tail)
25 | def headNames: DotName = DotName(names.reverse.tail.reverse)
26 | def tailNames: DotName = DotName(names.tail)
27 | def firstName: Name = names.head
28 | def lastName: Name = names.last
29 |
30 | def append(name: Name): DotName = DotName(names :+ name)
31 | def prepend(name: Name): DotName = DotName(name +: names)
32 | def prepend(name: Option[Name]): DotName = {
33 | name match {
34 | case Some(value) => DotName(value +: names)
35 | case _ => this
36 | }
37 | }
38 |
39 | def asTypeName(): TypeName = {
40 | TypeName(names.reverse)
41 | }
42 |
43 | override def toString: String = names.mkString(".")
44 | }
45 |
46 | object DotName {
47 | def apply(name: String): DotName = {
48 | DotName(name.split('.').toSeq.map(p => Name(p)))
49 | }
50 | def apply(name: Name): DotName = {
51 | DotName(Seq(name))
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/names/Name.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.names
15 |
16 | import upickle.default.{macroRW, ReadWriter => RW}
17 |
18 | /** Case insensitive string for symbol names.
19 | *
20 | * The value of the Name is stored as is but equality and hashing are performed against a normalised lower case
21 | * value.
22 | */
23 | @upickle.implicits.key("Name")
24 | final case class Name(value: String) {
25 |
26 | override val hashCode: Int = value.toLowerCase.hashCode
27 |
28 | def canEqual(that: Any): Boolean = that.isInstanceOf[Name]
29 |
30 | override def equals(that: Any): Boolean = {
31 | that match {
32 | case otherName: Name =>
33 | otherName.canEqual(this) && otherName.value.equalsIgnoreCase(value)
34 | case _ => false
35 | }
36 | }
37 |
38 | override def toString: String = value
39 | }
40 |
41 | object Name {
42 | implicit val rw: RW[Name] = macroRW
43 |
44 | val empty: Name = new Name("")
45 | }
46 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/parsers/UTF8Decode.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.parsers
15 |
16 | /* Utilities for helping find character positions in UTF-8 byte arrays. Character positions can be ambiguous as they
17 | * have commonly be used to refer to UTF-16 positions rather than Unicode code points. This code assumes the latter
18 | * model to match ANTLR CharStream handling of positions.
19 | */
20 | object UTF8Decode {
21 |
22 | def isASCII(buffer: Array[Byte], offset: Int, length: Int): Boolean = {
23 | var at = offset
24 | val limit = offset + length
25 | while (at < limit) {
26 | if ((0xff & buffer(at).asInstanceOf[Int]) >= 0x80)
27 | return false
28 | at += 1
29 | }
30 | true
31 | }
32 |
33 | def getCharOffsetFrom(buffer: Array[Byte], offset: Int, charCount: Int): Int = {
34 | var remaining = charCount
35 | var at = offset
36 | while (remaining > 0) {
37 | at += sequenceLength(buffer(at))
38 | remaining -= 1
39 | }
40 | at
41 | }
42 |
43 | private def sequenceLength(leadingByte: Byte): Int = {
44 | val unsigned: Int = 0xff & leadingByte.asInstanceOf[Int]
45 | if (unsigned < 0x80) 1
46 | else if ((unsigned >> 5) == 0x6) 2
47 | else if ((unsigned >> 4) == 0xe) 3
48 | else if ((unsigned >> 3) == 0x1e) 4
49 | else
50 | throw new IllegalArgumentException(s"Expecting UTF-8 data, found leading byte: $leadingByte")
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/path/PathFactory.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.path
15 |
16 | import com.nawforce.runtime.platform.Path
17 |
18 | object PathFactory {
19 | def apply(path: String): PathLike = Path(path)
20 | def unapply(path: Path): Option[String] = Some(path.toString)
21 | }
22 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/sfdx/ModuleDependent.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.sfdx
15 |
16 | import com.nawforce.pkgforce.path.Location
17 | import ujson.Value
18 |
19 | case class ModuleDependent(config: ValueWithPositions, value: Value.Value) {
20 | val location: Location = config
21 | .lineAndOffsetOf(value)
22 | .map(lineAndOffset => Location(lineAndOffset._1, lineAndOffset._2))
23 | .getOrElse(Location.empty)
24 | val name: String = value.stringValue(config, "package")
25 | val version: Option[VersionNumber] = value.optVersionNumber(config, "versionNumber")
26 | }
27 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/sfdx/PackageDependent.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.sfdx
15 |
16 | import com.nawforce.pkgforce.names.Name
17 | import com.nawforce.pkgforce.path.{Location, PathLike}
18 | import ujson.Value
19 |
20 | case class PackageDependent(projectPath: PathLike, config: ValueWithPositions, value: Value.Value) {
21 |
22 | val location: Location =
23 | config
24 | .lineAndOffsetOf(value)
25 | .map(lineAndOffset => Location(lineAndOffset._1, lineAndOffset._2))
26 | .getOrElse(Location.empty)
27 |
28 | val namespace: Option[Name] =
29 | value.optIdentifier(config, "namespace") match {
30 | case Some(ns) if ns.value.isEmpty =>
31 | config
32 | .lineAndOffsetOf(value("namespace"))
33 | .map(lineAndOffset => {
34 | throw SFDXProjectError(lineAndOffset, "'namespace' can not be empty")
35 | })
36 | case Some(ns) => Some(ns)
37 | case None => None
38 | }
39 |
40 | val relativePath: Option[String] = value.optStringValue(config, "path")
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/sfdx/VersionNumber.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.sfdx
15 |
16 | sealed trait BuildNumber
17 | case object NextBuild extends BuildNumber
18 | case object LatestBuild extends BuildNumber
19 | case class Build(build: Int) extends BuildNumber
20 |
21 | case class VersionNumber(major: Int, minor: Int, patch: Int, build: BuildNumber) {
22 | def isCompatible(other: VersionNumber): Boolean = {
23 | if (major != other.major || minor != other.minor || patch != other.patch)
24 | return false
25 |
26 | (build, other.build) match {
27 | case (Build(x), Build(y)) => x == y
28 | case (LatestBuild, _) => true
29 | case _ => false
30 | }
31 | }
32 |
33 | override def toString: String = {
34 | s"$major.$minor.$patch." + (build match {
35 | case Build(n) => s"$n"
36 | case NextBuild => "NEXT"
37 | case LatestBuild => "LATEST"
38 | })
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/sfdx/WorkspaceConfig.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.sfdx
15 |
16 | import com.nawforce.pkgforce.diagnostics.IssueLogger
17 | import com.nawforce.pkgforce.names.Name
18 | import com.nawforce.pkgforce.path.PathLike
19 | import com.nawforce.pkgforce.workspace.{ModuleLayer, NamespaceLayer}
20 |
21 | trait WorkspaceConfig {
22 | def layers(logger: IssueLogger): Seq[NamespaceLayer]
23 | }
24 |
25 | class MDAPIWorkspaceConfig(namespace: Option[Name], paths: Seq[PathLike]) extends WorkspaceConfig {
26 |
27 | override def layers(logger: IssueLogger): Seq[NamespaceLayer] =
28 | Seq(
29 | NamespaceLayer(
30 | namespace,
31 | isGulped = false,
32 | paths.map(path => ModuleLayer(path, ".", Seq())).toList
33 | )
34 | )
35 |
36 | override def toString: String =
37 | s"MDAPIWorkspace(namespace=$namespace, paths=${paths.map(_.toString).mkString(", ")})"
38 | }
39 |
40 | class SFDXWorkspaceConfig(val rootPath: PathLike, project: SFDXProject) extends WorkspaceConfig {
41 |
42 | override def layers(logger: IssueLogger): Seq[NamespaceLayer] = project.layers(logger)
43 |
44 | override def toString: String = s"SFDXWorkspace(${project.projectPath})"
45 | }
46 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/stream/ApexGenerator.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.pkgforce.stream
16 |
17 | import com.nawforce.pkgforce.documents._
18 | import com.nawforce.pkgforce.path.PathLike
19 |
20 | final case class ApexEvent(path: PathLike) extends PackageEvent
21 |
22 | /** Convert Apex documents into PackageEvents */
23 | object ApexGenerator {
24 |
25 | def iterator(index: DocumentIndex): Iterator[PackageEvent] =
26 | index.get(ApexNature).flatMap(toEvents)
27 |
28 | private def toEvents(document: MetadataDocument): Iterator[PackageEvent] = {
29 | Iterator(ApexEvent(document.path))
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/stream/FlowGenerator.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.pkgforce.stream
16 |
17 | import com.nawforce.pkgforce.documents._
18 | import com.nawforce.pkgforce.path.{Location, PathLocation}
19 |
20 | final case class FlowEvent(sourceInfo: SourceInfo) extends PackageEvent
21 |
22 | object FlowGenerator {
23 | def iterator(index: DocumentIndex): Iterator[PackageEvent] =
24 | index.get(FlowNature).flatMap(toEvents)
25 |
26 | private def toEvents(document: MetadataDocument): Iterator[PackageEvent] = {
27 | val source = document.source
28 | source.value
29 | .map(source => {
30 | Iterator(FlowEvent(SourceInfo(PathLocation(document.path, Location.all), source)))
31 | })
32 | .getOrElse(Iterator.empty) ++ IssuesEvent.iterator(source.issues)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/stream/PackageStream.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.stream
15 |
16 | import com.nawforce.pkgforce.diagnostics.Issue
17 | import com.nawforce.pkgforce.documents._
18 |
19 | import scala.collection.compat.immutable.ArraySeq
20 |
21 | trait PackageEvent
22 |
23 | final case class IssuesEvent(issues: ArraySeq[Issue]) extends PackageEvent
24 |
25 | object IssuesEvent {
26 | def apply(issues: Issue*): IssuesEvent = {
27 | new IssuesEvent(issues.to(ArraySeq))
28 | }
29 |
30 | def iterator(issues: ArraySeq[Issue]): Iterator[IssuesEvent] = {
31 | if (issues.nonEmpty)
32 | Iterator(new IssuesEvent(issues.to(ArraySeq)))
33 | else
34 | Iterator.empty
35 | }
36 | }
37 |
38 | class PackageStream(val events: ArraySeq[PackageEvent]) {
39 | def issues: ArraySeq[IssuesEvent] = events.collect { case e: IssuesEvent => e }
40 |
41 | def labelsFiles: ArraySeq[LabelFileEvent] = events.collect { case e: LabelFileEvent => e }
42 |
43 | def labels: ArraySeq[LabelEvent] = events.collect { case e: LabelEvent => e }
44 |
45 | def pages: ArraySeq[PageEvent] = events.collect { case e: PageEvent => e }
46 |
47 | def flows: ArraySeq[FlowEvent] = events.collect { case e: FlowEvent => e }
48 |
49 | def components: ArraySeq[ComponentEvent] = events.collect { case e: ComponentEvent => e }
50 | }
51 |
52 | object PackageStream {
53 | def apply(index: DocumentIndex): PackageStream = {
54 | new PackageStream(ArraySeq.unsafeWrapArray(eventStream(index).toArray))
55 | }
56 |
57 | def eventStream(index: DocumentIndex): Iterator[PackageEvent] = {
58 | LabelGenerator.iterator(index) ++
59 | ComponentGenerator.iterator(index) ++
60 | PageGenerator.iterator(index) ++
61 | FlowGenerator.iterator(index) ++
62 | SObjectGenerator.iterator(index) ++
63 | ApexGenerator.iterator(index) ++
64 | TriggerGenerator.iterator(index)
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/stream/PageGenerator.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.pkgforce.stream
16 |
17 | import com.nawforce.pkgforce.diagnostics.CatchingLogger
18 | import com.nawforce.pkgforce.documents._
19 | import com.nawforce.pkgforce.names.Name
20 | import com.nawforce.pkgforce.path.{LocationAnd, PathLocation}
21 | import com.nawforce.runtime.parsers.PageParser
22 |
23 | import scala.collection.compat.immutable.ArraySeq
24 |
25 | final case class PageEvent(
26 | sourceInfo: SourceInfo,
27 | _controllers: ArraySeq[LocationAnd[Name]],
28 | _expressions: ArraySeq[LocationAnd[String]]
29 | ) extends VFEvent(_controllers, _expressions)
30 |
31 | /** Convert page documents into PackageEvents */
32 | object PageGenerator {
33 |
34 | def iterator(index: DocumentIndex): Iterator[PackageEvent] =
35 | index.get(PageNature).flatMap(toEvents)
36 |
37 | private def toEvents(document: MetadataDocument): Iterator[PackageEvent] = {
38 | val source = document.source
39 | source.value
40 | .map(source => {
41 | val parser: PageParser = PageParser(document.path, source)
42 | val result = parser.parsePage()
43 | if (result.issues.nonEmpty) {
44 | IssuesEvent.iterator(result.issues)
45 | } else {
46 | val location = parser.getPathLocation(result.value)
47 | val logger = new CatchingLogger
48 | Iterator(
49 | PageEvent(
50 | SourceInfo(PathLocation(location.path, location.location), source),
51 | VFEvent.extractControllers(parser.source, result.value, isPage = true),
52 | VFEvent.extractExpressions(parser.source, result.value)
53 | )
54 | ) ++
55 | IssuesEvent.iterator(logger.issues)
56 | }
57 | })
58 | .getOrElse(Iterator.empty) ++ IssuesEvent.iterator(source.issues)
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/stream/TriggerGenerator.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.pkgforce.stream
16 |
17 | import com.nawforce.pkgforce.documents._
18 | import com.nawforce.pkgforce.path.PathLike
19 |
20 | final case class TriggerEvent(path: PathLike) extends PackageEvent
21 |
22 | /** Convert trigger documents into PackageEvents */
23 | object TriggerGenerator {
24 |
25 | def iterator(index: DocumentIndex): Iterator[PackageEvent] =
26 | index.get(TriggerNature).flatMap(toEvents)
27 |
28 | private def toEvents(document: MetadataDocument): Iterator[PackageEvent] = {
29 | Iterator(TriggerEvent(document.path))
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/main/scala/com/nawforce/pkgforce/xml/XMLFactory.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.xml
15 |
16 | import com.nawforce.pkgforce.diagnostics.{Diagnostic, ERROR_CATEGORY, Issue, IssuesAnd}
17 | import com.nawforce.pkgforce.path.{Location, PathLike}
18 | import com.nawforce.runtime.xml.XMLDocument
19 |
20 | import scala.collection.immutable.ArraySeq
21 |
22 | object XMLFactory {
23 | def parse(path: PathLike): IssuesAnd[Option[XMLDocument]] = {
24 | path.readSourceData() match {
25 | case Left(err) =>
26 | IssuesAnd(ArraySeq(Issue(path, Diagnostic(ERROR_CATEGORY, Location(0), err))), None)
27 | case Right(data) => XMLDocument(path, data)
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/test/scala/com/nawforce/pkgforce/diagnostics/LoggerTest.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2019 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 |
15 | package com.nawforce.pkgforce.diagnostics
16 |
17 | import org.scalatest.BeforeAndAfter
18 | import org.scalatest.funsuite.AnyFunSuite
19 |
20 | class LoggerTest extends AnyFunSuite with BeforeAndAfter {
21 | test("exception logger to string") {
22 | val ex = new Exception("Hello")
23 | assert(LoggerOps.exceptionMessage(ex).startsWith("java.lang.Exception: Hello"))
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/pkgforce/shared/src/test/scala/com/nawforce/pkgforce/parsers/SourceDataTest.scala:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 Kevin Jones, All rights reserved.
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions
5 | are met:
6 | 1. Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | 2. Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | 3. The name of the author may not be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 | */
14 | package com.nawforce.pkgforce.parsers
15 |
16 | import com.nawforce.runtime.parsers.SourceData
17 | import org.scalatest.funsuite.AnyFunSuite
18 |
19 | class SourceDataTest extends AnyFunSuite {
20 |
21 | test("Basic string handling") {
22 | val sd = SourceData("A basic test string")
23 | assert(sd.subdata(2, 2).asString.isEmpty)
24 | assert(sd.subdata(2, 3).asString == "b")
25 | assert(sd.subdata(2, 7).asString == "basic")
26 | }
27 |
28 | test("UTF-8 String handling") {
29 | // Single char, two byte UTF-8, 1 Unicode code point
30 | val sd = SourceData("A UTF-8 \u00E9 test string")
31 | assert(sd.subdata(8, 9).asString == "\u00E9")
32 | assert(sd.subdata(10, 11).asString == "t")
33 | assert(sd.subdata(10, 14).asString == "test")
34 | assert(sd.subdata(6, 14).asString == "8 \u00E9 test")
35 | }
36 |
37 | test("UTF-8 String handling (surrogate pair)") {
38 | // Two UTF-16 chars, four byte UTF-8, should be handled as 1 Unicode code point for ANTLR CharSource compat
39 | val sd = SourceData("A UTF-8 \uD83E\uDD26 test string")
40 | assert(sd.subdata(8, 9).asString == "\uD83E\uDD26")
41 | assert(sd.subdata(10, 11).asString == "t")
42 | assert(sd.subdata(10, 14).asString == "test")
43 | assert(sd.subdata(6, 14).asString == "8 \uD83E\uDD26 test")
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
5 | 4.0.0
6 |
7 | com.github.nawforce
8 | apexlink-parent
9 | 2.3.7
10 | pom
11 |
12 | apexlink parent
13 |
14 |
15 | pkgforce
16 | apexlink
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/samples/Cumulus/sfdx-project.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageDirectories": [
3 | {
4 | "path": "Cumulus/force-app",
5 | "default": true
6 | }
7 | ],
8 | "namespace": "npsp",
9 | "sourceApiVersion": "48.0",
10 | "plugins": {
11 | "dependencies": [
12 | {"namespace": "npe01"},
13 | {"namespace": "npo02"},
14 | {"namespace": "npe03"},
15 | {"namespace": "npe4"},
16 | {"namespace": "npe5"}
17 | ]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/samples/FindNearby/sfdx-project.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageDirectories": [
3 | {
4 | "path": "FindNearBy/src",
5 | "default": true
6 | }
7 | ],
8 | "namespace": "FN",
9 | "sourceApiVersion": "48.0"
10 | }
11 |
--------------------------------------------------------------------------------
/samples/HyperBatch/sfdx-project.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageDirectories": [
3 | {
4 | "path": "HyperBatch/src",
5 | "default": true
6 | }
7 | ],
8 | "sourceApiVersion": "48.0"
9 | }
--------------------------------------------------------------------------------
/samples/Interactions-for-Student-Recruitment/extra/README.md:
--------------------------------------------------------------------------------
1 | The code is making direct reference to DmlWrapper, likely its within a the hed namespace but I have borrowed
2 | this copt from Cumulus so the sameple can still be used for testing.
--------------------------------------------------------------------------------
/samples/Interactions-for-Student-Recruitment/sfdx-project.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageDirectories": [
3 | {
4 | "path": "extra",
5 | "default": false
6 | },
7 | {
8 | "path": "Interactions-for-Student-Recruitment/src",
9 | "default": true
10 | }
11 | ],
12 | "sourceApiVersion": "48.0",
13 | "plugins": {
14 | "dependencies": [
15 | {"namespace": "hed"}
16 | ]
17 | }
18 | }
--------------------------------------------------------------------------------
/samples/NPSP/sfdx-project.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageDirectories": [
3 | {
4 | "path": "NPSP/force-app",
5 | "default": true
6 | }
7 | ],
8 | "namespace": "npsp",
9 | "sourceApiVersion": "48.0",
10 | "plugins": {
11 | "dependencies": [
12 | {"namespace": "npe01"},
13 | {"namespace": "npo02"},
14 | {"namespace": "npe03"},
15 | {"namespace": "npe4"},
16 | {"namespace": "npe5"}
17 | ]
18 | }
19 | }
--------------------------------------------------------------------------------
/samples/at4dx/sfdx-project.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageDirectories": [
3 | {
4 | "path": "fflib-apex-mocks/sfdx-source/apex-mocks",
5 | "default": false
6 | },
7 | {
8 | "path": "fflib-apex-common/sfdx-source/apex-common",
9 | "default": false
10 | },
11 | {
12 | "path": "force-di/force-di",
13 | "default": false
14 | },
15 | {
16 | "path": "at4dx/sfdx-source/core",
17 | "default": true
18 | }
19 | ],
20 | "namespace": "",
21 | "sfdcLoginUrl": "https://login.salesforce.com",
22 | "sourceApiVersion": "51.0"
23 | }
24 |
--------------------------------------------------------------------------------
/samples/fflib-apex-common-samplecode/sfdx-project.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageDirectories": [
3 | {
4 | "path": "fflib-apex-mocks/sfdx-source/apex-mocks",
5 | "default": false
6 | },
7 | {
8 | "path": "fflib-apex-common/sfdx-source/apex-common",
9 | "default": false
10 | },
11 | {
12 | "path": "fflib-apex-common-samplecode/sfdx-source/apex-common-samplecode",
13 | "default": true
14 | }
15 | ],
16 | "namespace": "",
17 | "sfdcLoginUrl": "https://login.salesforce.com",
18 | "sourceApiVersion": "51.0"
19 | }
20 |
--------------------------------------------------------------------------------
/samples/purealoe-lwc/.forceignore:
--------------------------------------------------------------------------------
1 | # List files or directories below to ignore them when running force:source:push, force:source:pull, and force:source:status
2 | # More information: https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_exclude_source.htm
3 | #
4 |
5 | # Standard metadata
6 | purealoe-lwc/package.xml
7 | purealoe-lwc/**appMenu
8 | purealoe-lwc/**appSwitcher
9 | purealoe-lwc/**objectTranslations
10 | purealoe-lwc/**profiles
11 | purealoe-lwc/**settings
12 |
13 | # LWC configuration files
14 | purealoe-lwc/**/jsconfig.json
15 | purealoe-lwc/**/.eslintrc.json
16 |
17 | # LWC Jest
18 | purealoe-lwc/**/__tests__/**
19 |
20 | purealoe-lwc/force-app/main/default/objects/Einstein_Settings__c.object
21 |
22 |
--------------------------------------------------------------------------------
/samples/purealoe-lwc/sfdx-project.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageDirectories": [
3 | {
4 | "path": "purealoe-lwc/force-app",
5 | "default": true,
6 | "package": "PureAloeLWC",
7 | "versionNumber": "4.0.0.NEXT",
8 | "versionName": "Spring '20"
9 | }
10 | ],
11 | "namespace": "",
12 | "sfdcLoginUrl": "https://login.salesforce.com",
13 | "sourceApiVersion": "48.0",
14 | "packageAliases": {
15 | "PureAloeLWC": "0HoB0000000Gmi9KAC",
16 | "PureAloeLWC@4.0.0-17": "04tB0000000Azj5IAC"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/samples/synthetic/dependency-counts/.forceignore:
--------------------------------------------------------------------------------
1 | # List files or directories below to ignore them when running force:source:push, force:source:pull, and force:source:status
2 | # More information: https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_exclude_source.htm
3 | #
4 |
5 | package.xml
6 |
7 | # LWC configuration files
8 | **/jsconfig.json
9 | **/.eslintrc.json
10 |
11 | # LWC Jest
12 | **/__tests__/**
--------------------------------------------------------------------------------
/samples/synthetic/dependency-counts/.gitignore:
--------------------------------------------------------------------------------
1 | # This file is used for Git repositories to specify intentionally untracked files that Git should ignore.
2 | # If you are not using git, you can delete this file. For more information see: https://git-scm.com/docs/gitignore
3 | # For useful gitignore templates see: https://github.com/github/gitignore
4 |
5 | # Salesforce cache
6 | .sfdx/
7 | .localdevserver/
8 |
9 | # LWC VSCode autocomplete
10 | **/lwc/jsconfig.json
11 |
12 | # LWC Jest coverage reports
13 | coverage/
14 |
15 | # Logs
16 | logs
17 | *.log
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
21 |
22 | # Dependency directories
23 | node_modules/
24 |
25 | # Eslint cache
26 | .eslintcache
27 |
28 | # MacOS system files
29 | .DS_Store
30 |
31 | # Windows system files
32 | Thumbs.db
33 | ehthumbs.db
34 | [Dd]esktop.ini
35 | $RECYCLE.BIN/
36 |
--------------------------------------------------------------------------------
/samples/synthetic/dependency-counts/force-app/main/default/classes/NoDeps.cls:
--------------------------------------------------------------------------------
1 | public class NoDeps {
2 | public void func() {}
3 | }
--------------------------------------------------------------------------------
/samples/synthetic/dependency-counts/force-app/main/default/classes/NoDeps.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 48.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/samples/synthetic/dependency-counts/force-app/main/default/classes/SingleDep.cls:
--------------------------------------------------------------------------------
1 | public class SingleDep {
2 | static void func() {
3 | NoDeps n = new NoDeps();
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/samples/synthetic/dependency-counts/force-app/main/default/classes/SingleDep.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 48.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/samples/synthetic/dependency-counts/force-app/main/default/classes/TestDep.cls:
--------------------------------------------------------------------------------
1 | @isTest
2 | public class TestDep {
3 | @isTest
4 | static void test_func() {
5 | SingleDep s = new SingleDep();
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/samples/synthetic/dependency-counts/force-app/main/default/classes/TestDep.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 48.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/samples/synthetic/dependency-counts/force-app/main/default/classes/TransDep.cls:
--------------------------------------------------------------------------------
1 | public class TransDep {
2 | public void func() {
3 | SingleDep s = new SingleDep();
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/samples/synthetic/dependency-counts/force-app/main/default/classes/TransDep.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 48.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/samples/synthetic/dependency-counts/sfdx-project.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageDirectories": [
3 | {
4 | "path": "force-app",
5 | "default": true
6 | }
7 | ],
8 | "namespace": "",
9 | "sfdcLoginUrl": "https://login.salesforce.com",
10 | "sourceApiVersion": "48.0"
11 | }
--------------------------------------------------------------------------------
/samples/synthetic/mdapi-test/Hello.cls:
--------------------------------------------------------------------------------
1 | public class Hello {
2 | public final static String Hello = 'Hello' + World.message;
3 | }
4 |
--------------------------------------------------------------------------------
/samples/synthetic/mdapi-test/Hello.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 48.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/samples/synthetic/mdapi-test/World.cls:
--------------------------------------------------------------------------------
1 | public class World {
2 | public final static String message = 'World';
3 | }
4 |
--------------------------------------------------------------------------------
/samples/synthetic/mdapi-test/World.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 48.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/samples/synthetic/sfdx-ns-test/.forceignore:
--------------------------------------------------------------------------------
1 | # List files or directories below to ignore them when running force:source:push, force:source:pull, and force:source:status
2 | # More information: https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_exclude_source.htm
3 | #
4 |
5 | package.xml
6 |
7 | # LWC configuration files
8 | **/jsconfig.json
9 | **/.eslintrc.json
10 |
11 | # LWC Jest
12 | **/__tests__/**
--------------------------------------------------------------------------------
/samples/synthetic/sfdx-ns-test/.gitignore:
--------------------------------------------------------------------------------
1 | # This file is used for Git repositories to specify intentionally untracked files that Git should ignore.
2 | # If you are not using git, you can delete this file. For more information see: https://git-scm.com/docs/gitignore
3 | # For useful gitignore templates see: https://github.com/github/gitignore
4 |
5 | # Salesforce cache
6 | .sfdx/
7 | .localdevserver/
8 |
9 | # LWC VSCode autocomplete
10 | **/lwc/jsconfig.json
11 |
12 | # LWC Jest coverage reports
13 | coverage/
14 |
15 | # Logs
16 | logs
17 | *.log
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
21 |
22 | # Dependency directories
23 | node_modules/
24 |
25 | # Eslint cache
26 | .eslintcache
27 |
28 | # MacOS system files
29 | .DS_Store
30 |
31 | # Windows system files
32 | Thumbs.db
33 | ehthumbs.db
34 | [Dd]esktop.ini
35 | $RECYCLE.BIN/
36 |
--------------------------------------------------------------------------------
/samples/synthetic/sfdx-ns-test/force-app/main/default/classes/DoubleError.cls:
--------------------------------------------------------------------------------
1 | public class DoubleError {
2 |
3 | public void func1() {debug}
4 |
5 | public void func2() {debug}
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/samples/synthetic/sfdx-ns-test/force-app/main/default/classes/DoubleError.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 48.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/samples/synthetic/sfdx-ns-test/force-app/main/default/classes/Hello.cls:
--------------------------------------------------------------------------------
1 | public class Hello {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/samples/synthetic/sfdx-ns-test/force-app/main/default/classes/Hello.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 48.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/samples/synthetic/sfdx-ns-test/force-app/main/default/classes/SingleError.cls:
--------------------------------------------------------------------------------
1 | public class SingleError {
2 | public void func() {
3 | }
4 |
--------------------------------------------------------------------------------
/samples/synthetic/sfdx-ns-test/force-app/main/default/classes/SingleError.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 48.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/samples/synthetic/sfdx-ns-test/sfdx-project.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageDirectories": [
3 | {
4 | "path": "force-app",
5 | "default": true
6 | }
7 | ],
8 | "namespace": "sfdx_test",
9 | "sfdcLoginUrl": "https://login.salesforce.com",
10 | "sourceApiVersion": "48.0"
11 | }
12 |
--------------------------------------------------------------------------------
/samples/synthetic/sfdx-test/.forceignore:
--------------------------------------------------------------------------------
1 | # List files or directories below to ignore them when running force:source:push, force:source:pull, and force:source:status
2 | # More information: https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_exclude_source.htm
3 | #
4 |
5 | package.xml
6 |
7 | # LWC configuration files
8 | **/jsconfig.json
9 | **/.eslintrc.json
10 |
11 | # LWC Jest
12 | **/__tests__/**
--------------------------------------------------------------------------------
/samples/synthetic/sfdx-test/.gitignore:
--------------------------------------------------------------------------------
1 | # This file is used for Git repositories to specify intentionally untracked files that Git should ignore.
2 | # If you are not using git, you can delete this file. For more information see: https://git-scm.com/docs/gitignore
3 | # For useful gitignore templates see: https://github.com/github/gitignore
4 |
5 | # Salesforce cache
6 | .sfdx/
7 | .localdevserver/
8 |
9 | # LWC VSCode autocomplete
10 | **/lwc/jsconfig.json
11 |
12 | # LWC Jest coverage reports
13 | coverage/
14 |
15 | # Logs
16 | logs
17 | *.log
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
21 |
22 | # Dependency directories
23 | node_modules/
24 |
25 | # Eslint cache
26 | .eslintcache
27 |
28 | # MacOS system files
29 | .DS_Store
30 |
31 | # Windows system files
32 | Thumbs.db
33 | ehthumbs.db
34 | [Dd]esktop.ini
35 | $RECYCLE.BIN/
36 |
--------------------------------------------------------------------------------
/samples/synthetic/sfdx-test/force-app/main/default/classes/Hello.cls:
--------------------------------------------------------------------------------
1 | public class Hello {
2 |
3 | }
--------------------------------------------------------------------------------
/samples/synthetic/sfdx-test/force-app/main/default/classes/Hello.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 48.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/samples/synthetic/sfdx-test/sfdx-project.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageDirectories": [
3 | {
4 | "path": "force-app",
5 | "default": true
6 | }
7 | ],
8 | "namespace": "",
9 | "sfdcLoginUrl": "https://login.salesforce.com",
10 | "sourceApiVersion": "48.0"
11 | }
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/.forceignore:
--------------------------------------------------------------------------------
1 | # List files or directories below to ignore them when running force:source:push, force:source:pull, and force:source:status
2 | # More information: https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_exclude_source.htm
3 | #
4 |
5 | package.xml
6 |
7 | # LWC configuration files
8 | **/jsconfig.json
9 | **/.eslintrc.json
10 |
11 | # LWC Jest
12 | **/__tests__/**
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/.gitignore:
--------------------------------------------------------------------------------
1 | # This file is used for Git repositories to specify intentionally untracked files that Git should ignore.
2 | # If you are not using git, you can delete this file. For more information see: https://git-scm.com/docs/gitignore
3 | # For useful gitignore templates see: https://github.com/github/gitignore
4 |
5 | # Salesforce cache
6 | .sfdx/
7 | .localdevserver/
8 |
9 | # LWC VSCode autocomplete
10 | **/lwc/jsconfig.json
11 |
12 | # LWC Jest coverage reports
13 | coverage/
14 |
15 | # Logs
16 | logs
17 | *.log
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
21 |
22 | # Dependency directories
23 | node_modules/
24 |
25 | # Eslint cache
26 | .eslintcache
27 |
28 | # MacOS system files
29 | .DS_Store
30 |
31 | # Windows system files
32 | Thumbs.db
33 | ehthumbs.db
34 | [Dd]esktop.ini
35 | $RECYCLE.BIN/
36 |
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/API.cls:
--------------------------------------------------------------------------------
1 | public interface API {
2 | void func();
3 | }
4 |
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/APIFactory.cls:
--------------------------------------------------------------------------------
1 | public class APIFactory {
2 | static API getInstance() {
3 | (API)type.forName('name');
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/APIImpl.cls:
--------------------------------------------------------------------------------
1 | public class APIImpl implements API {
2 | void func() {}
3 | }
4 |
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/APITest.cls:
--------------------------------------------------------------------------------
1 | @IsTest
2 | public class APITest {
3 | public testFunc() {
4 | API sut = APIFactory.getInstance();
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/Base.cls:
--------------------------------------------------------------------------------
1 | abstract public class Base implements API {
2 | abstract void func();
3 | }
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/BaseTest.cls:
--------------------------------------------------------------------------------
1 | @IsTest
2 | public class BaseTest {
3 |
4 | class TestImpl extends Base {
5 | public void func() {}
6 | }
7 |
8 | void testFunc() {
9 | TestImpl sut = new TestImpl();
10 |
11 | }
12 | }
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/Derived.cls:
--------------------------------------------------------------------------------
1 | public class Derived extends Base {
2 | void func () {}
3 | }
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/DerivedTest.cls:
--------------------------------------------------------------------------------
1 | @isTest
2 | public class DerivedTest {
3 | public void testFunc() {
4 | Derived sut = new Derived();
5 | }
6 | }
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/Hello.cls:
--------------------------------------------------------------------------------
1 | public class Hello {
2 | public void func() {}
3 | }
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/Hello.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 48.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/HelloTest.cls:
--------------------------------------------------------------------------------
1 | @IsTest
2 | public class HelloTest {
3 |
4 | static void testFunc() {
5 | Hello hello = new Hello();
6 | hello.func();
7 | }
8 |
9 | }
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/HelloTest.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 48.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/InnerServiceImpl.cls:
--------------------------------------------------------------------------------
1 | public class InnerServiceImpl{
2 | public class InnerImpl implements Service.API {
3 | void func() {}
4 |
5 | void foo() {
6 | Hello h = new Hello();
7 | }
8 | }
9 |
10 | public void bar() {
11 | NoTest n = new NoTest();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/NoTest.cls:
--------------------------------------------------------------------------------
1 | public class NoTest {
2 | public void func() {}
3 | }
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/NoTest.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 48.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/Service.cls:
--------------------------------------------------------------------------------
1 | public class Service {
2 | public interface API {
3 | void func();
4 | }
5 |
6 | static API getInstance() {
7 | (API)type.forName('name');
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/ServiceAPITest.cls:
--------------------------------------------------------------------------------
1 | @IsTest
2 | public class ServiceAPITest {
3 | void testFunc() {
4 | Service.API sut = Service.getInstance();
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/ServiceImpl.cls:
--------------------------------------------------------------------------------
1 | public class ServiceImpl implements Service.API {
2 | void func() {}
3 |
4 | void foo() {
5 | Hello h = new Hello();
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/force-app/main/default/classes/ServiceTest.cls:
--------------------------------------------------------------------------------
1 | @IsTest
2 | public class ServiceTest{
3 | public void testFunc() {
4 | Service sut = new Service();
5 | }
6 | }
--------------------------------------------------------------------------------
/samples/synthetic/test-classes/sfdx-project.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageDirectories": [
3 | {
4 | "path": "force-app",
5 | "default": true
6 | }
7 | ],
8 | "namespace": "",
9 | "sfdcLoginUrl": "https://login.salesforce.com",
10 | "sourceApiVersion": "48.0"
11 | }
--------------------------------------------------------------------------------