Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .github/workflows/Build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ jobs:
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 8
java-version: 17
cache: 'sbt'

- uses: sbt/setup-sbt@v1

- uses: actions/setup-node@v4
with:
node-version: 16
node-version: 22

- name: FormatCheck
run: sbt scalafmtCheck # Does not check test files currently
Expand All @@ -31,12 +33,12 @@ jobs:
run: sbt build

- name: Checkout samples repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
submodules: recursive
repository: apex-dev-tools/apex-samples
path: apex-samples
ref: v1.0.2
ref: v1.4.0

- name: Set samples env
run: echo "SAMPLES=$GITHUB_WORKSPACE/apex-samples" >> "$GITHUB_ENV"
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

This parser extracts an outline from Apex class files. The outline provides structural information about the class and its inner classes without needing to parse code blocks. The performance of this parser is much better than a full parser, making it ideal for use when indexing or similar activities.

This library includes the Apex type definitions (interfaces and base types) that were previously published separately as `apex-types`. Starting with version 2.0.0, these are bundled together to simplify dependency management.

If you need access to a full syntax tree for Apex, SOQL or SOSL we recommend using the [apex-parser](https://github.com/apex-dev-tools/apex-parser) instead.

## Getting Started
Expand Down
3 changes: 1 addition & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import org.scalajs.linker.interface.Report
import scala.sys.process._

ThisBuild / scalaVersion := "2.13.10"
ThisBuild / description := "Salesforce Apex outline parser"
ThisBuild / description := "Salesforce Apex outline parser with type definitions"
ThisBuild / organization := "io.github.apex-dev-tools"
ThisBuild / organizationHomepage := Some(url("https://github.com/apex-dev-tools/outline-parser"))
ThisBuild / homepage := Some(url("https://github.com/apex-dev-tools/outline-parser"))
Expand Down Expand Up @@ -42,7 +42,6 @@ lazy val parser = crossProject(JSPlatform, JVMPlatform)
name := "outline-parser",
scalacOptions += "-deprecation",
libraryDependencies ++= Seq(
"io.github.apex-dev-tools" %%% "apex-types" % "1.3.0",
"org.scalatest" %%% "scalatest" % "3.2.9" % Test,
"io.github.apex-dev-tools" %%% "apex-ls" % "4.3.1" % Test
)
Expand Down
47 changes: 47 additions & 0 deletions js/src/main/scala/io/github/apexdevtools/api/Issue.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
Copyright (c) 2021 Kevin Jones, All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
*/

package io.github.apexdevtools.api

/* WARNING: This must be identical to Java class of same name */
trait Issue {

/* The generator of this issue, default to APEX_LS_PROVIDER */
def provider(): String

/* The file path where the issue was found */
def filePath(): String

/* The location within the file */
def fileLocation(): IssueLocation

/* The rule violated, sets the issue priority */
def rule(): Rule

/* The issue message */
def message(): String

/* Is this considered an error issue, rather than a warning */
def isError: java.lang.Boolean

/* Format as String, filePath is omitted to avoid duplicating over multiple Issues */
def asString: String = rule().name() + ": " + fileLocation().displayPosition + ": " + message()

override def toString: String = filePath() + ": " + asString
}

object Issue {
// Default source name for apex-ls generated diagnostics
final val APEX_LS_PROVIDER = "apex-ls"
}
54 changes: 54 additions & 0 deletions js/src/main/scala/io/github/apexdevtools/api/IssueLocation.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
Copyright (c) 2021 Kevin Jones, All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
*/

package io.github.apexdevtools.api

/* WARNING: This must be identical to Java class of same name */
trait IssueLocation {
def startLineNumber(): Int
def startCharOffset(): Int
def endLineNumber(): Int
def endCharOffset(): Int

def displayPosition: String = {
if (
startLineNumber() == 1 && endLineNumber() == Int.MaxValue && startCharOffset() == 0 && endCharOffset() == 0
) {
s"line 1"
} else if (startLineNumber() == endLineNumber()) {
if (startCharOffset() == 0 && endCharOffset() == 0)
s"line ${startLineNumber()}"
else if (startCharOffset() == endCharOffset())
s"line ${startLineNumber()} at ${startCharOffset()}"
else
s"line ${startLineNumber()} at ${startCharOffset()}-${endCharOffset()}"
} else {
if (startCharOffset() == 0 && endCharOffset() == 0)
s"line ${startLineNumber()} to ${endLineNumber()}"
else
s"line ${startLineNumber()}:${startCharOffset()} to ${endLineNumber()}:${endCharOffset()}"
}
}

def contains(line: Int, offset: Int): Boolean = {
!(line < startLineNumber() || line > endLineNumber() ||
(line == startLineNumber() && offset < startCharOffset()) ||
(line == endLineNumber() && offset > endCharOffset()))
}

def contains(other: IssueLocation): Boolean = {
contains(other.startLineNumber(), other.startCharOffset()) &&
contains(other.endLineNumber(), other.endCharOffset())
}
}
34 changes: 34 additions & 0 deletions js/src/main/scala/io/github/apexdevtools/api/Rule.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Copyright (c) 2021 Kevin Jones, All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
*/

package io.github.apexdevtools.api

/* WARNING: This must be identical to Java class of same name */
trait Rule {
/* The nane of the rule */
def name(): String

/* Range 1-5, 1 being the highest */
def priority(): Integer
}

object Rule {
// Priority constants, these should become enums after moving to Scala3
// These are based on SonarQube, PMD uses Integer 1-5
final val BLOCKER_PRIORITY = 1 // Change absolutely required
final val CRITICAL_PRIORITY = 2 // Change highly recommended
final val MAJOR_PRIORITY = 3 // Change recommended
final val MINOR_PRIORITY = 4 // Change optional
final val INFO_PRIORITY = 5 // Change highly optional
}
67 changes: 67 additions & 0 deletions jvm/src/main/java/io/github/apexdevtools/api/Issue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
Copyright (c) 2021 Kevin Jones, All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
*/

package io.github.apexdevtools.api;

/**
* A diagnostic issue.
* Each issue must identify which provider generated it, the file path & location it refers to,
* a Rule the issue relates to, if the issue should be considered an error and message for
* the issue. This is based on the PMD model of a diagnostic issue.
* WARNING: This must be identical to Scala class of same name
*/
public abstract class Issue {

/**
* Name of provider which created this Issue
*/
public abstract String provider();

/**
* The file path where the issue was found
*/
public abstract String filePath();

/**
* The location within the file
*/
public abstract IssueLocation fileLocation();

/**
* The rule violated, sets the issue priority
*/
public abstract Rule rule();

/**
* Is this considered an error issue, rather than a warning
*/
public abstract Boolean isError();

/**
* The issue message
*/
public abstract String message();

/**
* Format as String, filePath is omitted to avoid duplicating over multiple Issues
*/
public String asString() {
return rule().name() + ": " + fileLocation().displayPosition() + ": " + message();
}

@Override
public String toString() {
return filePath() + ": " + asString();
}
}
58 changes: 58 additions & 0 deletions jvm/src/main/java/io/github/apexdevtools/api/IssueLocation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
Copyright (c) 2021 Kevin Jones, All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
*/

package io.github.apexdevtools.api;

/**
* Location of an Issue in a file.
* Line numbers start at 1, character offsets within a line start at 0.
* Assumes start position <= end position but does not validate this.
* WARNING: This must be identical to Scala class of same name
*/
public abstract class IssueLocation {
public abstract int startLineNumber();
public abstract int startCharOffset();
public abstract int endLineNumber();
public abstract int endCharOffset();

public String displayPosition() {
if (startLineNumber() == 1 && endLineNumber() == Integer.MAX_VALUE && startCharOffset() == 0 && endCharOffset() == 0) {
return "line 1";
}
if (startLineNumber() == endLineNumber()) {
if (startCharOffset() == 0 && endCharOffset() == 0)
return "line " + startLineNumber();
else if (startCharOffset() == endCharOffset())
return "line " + startLineNumber() + " at " + startCharOffset();
else
return "line " + startLineNumber() + " at " + startCharOffset() + "-" + endCharOffset();
} else {
if (startCharOffset() == 0 && endCharOffset() == 0)
return "line " + startLineNumber() + " to " + endLineNumber();
else
return "line " + startLineNumber() + ":" + startCharOffset() + " to " + endLineNumber() + ":" + endCharOffset();
}
}

public boolean contains(int line, int offset) {
return !(line < startLineNumber() || line > endLineNumber() ||
(line == startLineNumber() && offset < startCharOffset()) ||
(line == endLineNumber() && offset > endCharOffset()));
}

public boolean contains(IssueLocation other) {
return contains(other.startLineNumber(), other.startCharOffset()) &&
contains(other.endLineNumber(), other.endCharOffset());
}
}
55 changes: 55 additions & 0 deletions jvm/src/main/java/io/github/apexdevtools/api/Rule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
Copyright (c) 2021 Kevin Jones, All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
*/

package io.github.apexdevtools.api;

/**
* Analysis named rule.
* Provides basic information about the Rule.
* WARNING: This must be identical to Scala class of same name
*/
public interface Rule {
// Priority constants, these are based on SonarQube, PMD uses Integer 1-5

/**
* Change absolutely required
*/
Integer BLOCKER_PRIORITY = 1;
/**
* Change highly recommended
*/
Integer CRITICAL_PRIORITY = 2;
/**
* Change recommended
*/
Integer MAJOR_PRIORITY = 3;
/**
* Change optional
*/
Integer MINOR_PRIORITY = 4;
/**
* Change highly optional
*/
Integer INFO_PRIORITY = 5;

/**
* The nane of the rule, does need to be unique but recommended it is
*/
String name();

/**
* Priority Range 1-5, 1 being the highest
*/
Integer priority();
}
Loading
Loading