From 19868ef34865111ec85219f9e98421ac3f60f557 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Mon, 23 Dec 2024 10:55:01 +0000 Subject: [PATCH 1/2] Fix completion handling of visibility --- .../apexlink/cst/BodyDeclarations.scala | 4 +- .../nawforce/apexlink/cst/Properties.scala | 2 - .../apexlink/org/CompletionProvider.scala | 110 ++++--- .../apexlink/plugins/UnusedPlugin.scala | 2 +- .../apexlink/types/apex/FullDeclaration.scala | 2 +- .../apexlink/types/core/TypeDeclaration.scala | 43 +-- .../synthetic/CustomFieldDeclaration.scala | 3 +- .../synthetic/CustomMethodDeclaration.scala | 2 +- .../nawforce/apexlink/cst/PropertyTest.scala | 23 +- .../apexlink/pkg/CompletionProviderTest.scala | 290 +++++++++++------- .../pkgforce/modifiers/FieldModifiers.scala | 2 - .../pkgforce/modifiers/Modifier.scala | 4 +- .../modifiers/FieldModifierTest.scala | 76 ++--- 13 files changed, 314 insertions(+), 249 deletions(-) diff --git a/jvm/src/main/scala/com/nawforce/apexlink/cst/BodyDeclarations.scala b/jvm/src/main/scala/com/nawforce/apexlink/cst/BodyDeclarations.scala index 45ec7f36a..fe33fbb55 100644 --- a/jvm/src/main/scala/com/nawforce/apexlink/cst/BodyDeclarations.scala +++ b/jvm/src/main/scala/com/nawforce/apexlink/cst/BodyDeclarations.scala @@ -340,9 +340,7 @@ final case class ApexFieldDeclaration( override def idLocation: Location = id.location.location - override val name: Name = id.name - private val visibility: Option[Modifier] = - _modifiers.modifiers.find(ApexModifiers.visibilityModifiers.contains) + override val name: Name = id.name override val readAccess: Modifier = visibility.getOrElse(PRIVATE_MODIFIER) override val writeAccess: Modifier = readAccess override val children: ArraySeq[ApexNode] = ArraySeq.empty diff --git a/jvm/src/main/scala/com/nawforce/apexlink/cst/Properties.scala b/jvm/src/main/scala/com/nawforce/apexlink/cst/Properties.scala index cee3c682e..5eed069dd 100644 --- a/jvm/src/main/scala/com/nawforce/apexlink/cst/Properties.scala +++ b/jvm/src/main/scala/com/nawforce/apexlink/cst/Properties.scala @@ -57,8 +57,6 @@ final case class ApexPropertyDeclaration( case _ => None }.headOption - private val visibility: Option[Modifier] = - _modifiers.modifiers.find(m => ApexModifiers.visibilityModifiers.contains(m)) override val readAccess: Modifier = getter .flatMap(_.modifiers.modifiers.headOption) diff --git a/jvm/src/main/scala/com/nawforce/apexlink/org/CompletionProvider.scala b/jvm/src/main/scala/com/nawforce/apexlink/org/CompletionProvider.scala index 7732978ec..eeb0aa6c6 100644 --- a/jvm/src/main/scala/com/nawforce/apexlink/org/CompletionProvider.scala +++ b/jvm/src/main/scala/com/nawforce/apexlink/org/CompletionProvider.scala @@ -21,7 +21,7 @@ import com.nawforce.apexlink.rpc.CompletionItemLink import com.nawforce.apexlink.types.apex.{ApexClassDeclaration, ApexFullDeclaration} import com.nawforce.apexlink.types.core._ import com.nawforce.pkgforce.documents.{ApexClassDocument, ApexTriggerDocument, MetadataDocument} -import com.nawforce.pkgforce.modifiers.PUBLIC_MODIFIER +import com.nawforce.pkgforce.modifiers.{PRIVATE_MODIFIER, PROTECTED_MODIFIER, PUBLIC_MODIFIER} import com.nawforce.pkgforce.names.TypeName import com.nawforce.pkgforce.path.PathLike import com.vmware.antlr4c3.CodeCompletionCore @@ -55,8 +55,9 @@ trait CompletionProvider { if (classDetails._1.isEmpty) /* Bail if we did not at least parse the content */ return emptyCompletions - val parserAndCU = classDetails._1.get - val adjustedOffset = terminatedContent._2 + val parserAndCU = classDetails._1.get + val fromDeclaration = classDetails._2 + val adjustedOffset = terminatedContent._2 // Attempt to find a searchTerm for dealing with dot expressions lazy val searchTerm = @@ -64,9 +65,9 @@ trait CompletionProvider { // Setup to lazy validate the Class block to recover the validationResult for the cursor position lazy val validationResult: Option[ValidationResult] = { - if (classDetails._2.nonEmpty && searchTerm.nonEmpty) { + if (fromDeclaration.nonEmpty && searchTerm.nonEmpty) { val searchEnd = searchTerm.get.location.endPosition - val resultMap = classDetails._2.get.getValidationMap(line, searchEnd) + val resultMap = fromDeclaration.get.getValidationMap(line, searchEnd) val exprLocations = resultMap.keys.filter(_.contains(line, searchEnd)) val targetExpression = exprLocations.find(exprLocation => exprLocations.forall(_.contains(exprLocation))) @@ -94,8 +95,8 @@ trait CompletionProvider { .toArray val creatorCompletions = - if (classDetails._2.nonEmpty && keywords.map(_.label).contains("new")) { - getEmptyCreatorCompletionItems(classDetails._2.get, terminatedContent._3) + if (fromDeclaration.nonEmpty && keywords.map(_.label).contains("new")) { + getEmptyCreatorCompletionItems(fromDeclaration.get, terminatedContent._3) } else { emptyCompletions } @@ -109,6 +110,7 @@ trait CompletionProvider { .filter(_.result.declaration.nonEmpty) .map(validationResult => getAllCompletionItems( + fromDeclaration, validationResult.result.declaration.get, validationResult.result.isStatic, searchTerm.get.residualExpr @@ -122,8 +124,9 @@ trait CompletionProvider { /* Now for rule matches. These are not distinct cases, they might combine to give the correct result. */ var haveTypes = false val rules = candidates.rules.asScala - .collect(rule => - rule._1.toInt match { + .map(_._1.toInt) + .flatMap { id => + id match { /* TypeRefs appear in lots of places, e.g. inside Primaries but we just handle once for simplicity. */ case ApexParser.RULE_typeRef => if (haveTypes) Array[CompletionItemLink]() @@ -154,14 +157,7 @@ trait CompletionProvider { ) .toArray ++ classDetails._2 - .map(td => - getAllCompletionItems( - td, - None, - searchTerm.residualExpr, - hasPrivateAccess = true - ) - ) + .map(td => getAllCompletionItems(Some(td), td, None, searchTerm.residualExpr)) .getOrElse(Array()) ++ (if (haveTypes) Array[CompletionItemLink]() else { @@ -180,9 +176,10 @@ trait CompletionProvider { .map(m => m.matchTdsForModule(terminatedContent._3, offset)) .map(_.flatMap(td => getAllCreatorCompletionItems(td, classDetails._2))) .getOrElse(emptyCompletions) + + case _ => emptyCompletions } - ) - .flatten + } .toArray (if (creatorCompletions.nonEmpty) @@ -296,38 +293,54 @@ trait CompletionProvider { buffer.append(";") } + /** Return a list of completion items in targetDeclaration that can be accessed from fromDeclaration. + * The fromDeclaration is optional as we may not be able to construct due to parsing errors. + */ private def getAllCompletionItems( - td: TypeDeclaration, + fromDeclaration: Option[TypeDeclaration], + targetDeclaration: TypeDeclaration, isStatic: Option[Boolean], - filterBy: String, - hasPrivateAccess: Boolean = false + filterBy: String ): Array[CompletionItemLink] = { var items = Array[CompletionItemLink]() - items = items ++ td.methods + val minimumVisibility = + if (fromDeclaration.contains(targetDeclaration)) + PRIVATE_MODIFIER.order + else if (fromDeclaration.exists(_.extendsOrImplements(targetDeclaration.typeName))) + PROTECTED_MODIFIER.order + else PUBLIC_MODIFIER.order + + items = items ++ targetDeclaration.methods .filter(isStatic.isEmpty || _.isStatic == isStatic.get) - .filter(hasPrivateAccess || _.modifiers.contains(PUBLIC_MODIFIER)) + .filter(_.visibility.map(_.order).getOrElse(0) >= minimumVisibility) .map(method => CompletionItemLink(method)) - items = items ++ td.fields + items = items ++ targetDeclaration.fields .filter(isStatic.isEmpty || _.isStatic == isStatic.get) - .filter(hasPrivateAccess || _.modifiers.contains(PUBLIC_MODIFIER)) + .filter(_.visibility.map(_.order).getOrElse(0) >= minimumVisibility) .map(field => CompletionItemLink(field)) if (isStatic.isEmpty || isStatic.contains(true)) { - items = items ++ td.nestedTypes - .filter(hasPrivateAccess || _.modifiers.contains(PUBLIC_MODIFIER)) + items = items ++ targetDeclaration.nestedTypes + .filter(_.visibility.map(_.order).getOrElse(0) >= minimumVisibility) .flatMap(nested => CompletionItemLink(nested)) } if (isStatic.isEmpty) { - val superCtors = td.superClassDeclaration + val superConstructors = targetDeclaration.superClassDeclaration .map(superClass => { superClass.constructors - .filter(ctor => ConstructorMap.isCtorAccessible(ctor, td, td.superClassDeclaration)) - .map(ctor => + .filter(constructor => + ConstructorMap.isCtorAccessible( + constructor, + targetDeclaration, + targetDeclaration.superClassDeclaration + ) + ) + .map(constructor => ( - "super(" + ctor.parameters.map(_.name.toString()).mkString(", ") + ")", - ctor.toString + "super(" + constructor.parameters.map(_.name.toString()).mkString(", ") + ")", + constructor.toString ) ) .map(labelDetail => CompletionItemLink(labelDetail._1, "Constructor", labelDetail._2)) @@ -335,14 +348,23 @@ trait CompletionProvider { }) .getOrElse(emptyCompletions) - val thisCtors = td.constructors - .filter(ctor => ConstructorMap.isCtorAccessible(ctor, td, td.superClassDeclaration)) - .map(ctor => - ("this(" + ctor.parameters.map(_.name.toString()).mkString(", ") + ")", ctor.toString) + val thisConstructors = targetDeclaration.constructors + .filter(constructor => + ConstructorMap.isCtorAccessible( + constructor, + targetDeclaration, + targetDeclaration.superClassDeclaration + ) + ) + .map(constructor => + ( + "this(" + constructor.parameters.map(_.name.toString()).mkString(", ") + ")", + constructor.toString + ) ) .map(labelDetail => CompletionItemLink(labelDetail._1, "Constructor", labelDetail._2)) - items = items ++ thisCtors ++ superCtors + items = items ++ thisConstructors ++ superConstructors } if (filterBy.nonEmpty) @@ -358,8 +380,8 @@ trait CompletionProvider { callingFrom.map(td => (td, td.superClassDeclaration)) match { case Some((thisType, superType)) => itemsFor.constructors - .filter(ctor => ConstructorMap.isCtorAccessible(ctor, thisType, superType)) - .map(ctor => CompletionItemLink(itemsFor.name, ctor)) + .filter(constructor => ConstructorMap.isCtorAccessible(constructor, thisType, superType)) + .map(constructor => CompletionItemLink(itemsFor.name, constructor)) .toArray case None => emptyCompletions } @@ -378,7 +400,7 @@ trait CompletionProvider { findTrailingTypeName(trimmed) .flatMap(typeName => { TypeResolver(typeName, td).toOption - .filter(td => td.isSObject || td.constructors.exists(ctor => ctor.parameters.isEmpty)) + .filter(td => td.isSObject || td.constructors.exists(_.parameters.isEmpty)) .map(_ => new CompletionItemLink(s"new $typeName();", "Constructor", "")) }) .toArray @@ -395,12 +417,12 @@ trait CompletionProvider { object CompletionProvider { /* This limits how many states can be traversed during code completion, it provides a safeguard against run away * analysis but needs to be large enough for long files. */ - final val MAX_STATES: Int = 10000000 + private final val MAX_STATES: Int = 10000000 /* Match trailing 'id = n' as part of field/var creator pattern */ - final val idAssignPattern: Regex = "\\s*[0-9a-zA-Z_]+\\s*=\\s*n\\s*$".r + private final val idAssignPattern: Regex = "\\s*[0-9a-zA-Z_]+\\s*=\\s*n\\s*$".r - final val emptyCompletions: Array[CompletionItemLink] = Array[CompletionItemLink]() + private final val emptyCompletions: Array[CompletionItemLink] = Array[CompletionItemLink]() final val ignoredTokens: Set[Integer] = Set[Integer]( ApexLexer.LPAREN, diff --git a/jvm/src/main/scala/com/nawforce/apexlink/plugins/UnusedPlugin.scala b/jvm/src/main/scala/com/nawforce/apexlink/plugins/UnusedPlugin.scala index df3021872..2d139567a 100644 --- a/jvm/src/main/scala/com/nawforce/apexlink/plugins/UnusedPlugin.scala +++ b/jvm/src/main/scala/com/nawforce/apexlink/plugins/UnusedPlugin.scala @@ -162,7 +162,7 @@ class UnusedPlugin(td: DependentType) extends Plugin(td) { return false // Don't promote for global as these are implicitly used - if (td.visibility == GLOBAL_MODIFIER) + if (td.visibility.getOrElse(PRIVATE_MODIFIER) == GLOBAL_MODIFIER) return false // Exclude reporting on empty outers, that is just a bit harsh diff --git a/jvm/src/main/scala/com/nawforce/apexlink/types/apex/FullDeclaration.scala b/jvm/src/main/scala/com/nawforce/apexlink/types/apex/FullDeclaration.scala index caa123fdd..b77432b66 100644 --- a/jvm/src/main/scala/com/nawforce/apexlink/types/apex/FullDeclaration.scala +++ b/jvm/src/main/scala/com/nawforce/apexlink/types/apex/FullDeclaration.scala @@ -181,7 +181,7 @@ abstract class FullDeclaration( OrgInfo.logError(id.location, s"Parent type '${superClass.get.asDotName}' must be a class") } else if ( !inTest && - superClassDeclaration.visibility == PRIVATE_MODIFIER && + superClassDeclaration.visibility.getOrElse(PRIVATE_MODIFIER) == PRIVATE_MODIFIER && superClassDeclaration.outermostTypeDeclaration != outermostTypeDeclaration ) { // Private is OK with Outer extends Inner, Inner extends Inner or Test classes diff --git a/jvm/src/main/scala/com/nawforce/apexlink/types/core/TypeDeclaration.scala b/jvm/src/main/scala/com/nawforce/apexlink/types/core/TypeDeclaration.scala index b210dc2ca..600879161 100644 --- a/jvm/src/main/scala/com/nawforce/apexlink/types/core/TypeDeclaration.scala +++ b/jvm/src/main/scala/com/nawforce/apexlink/types/core/TypeDeclaration.scala @@ -31,14 +31,11 @@ import com.nawforce.apexlink.types.synthetic.{ CustomFieldDeclaration, LocatableCustomFieldDeclaration } -import com.nawforce.pkgforce.diagnostics.{ERROR_CATEGORY, Issue} import com.nawforce.pkgforce.modifiers._ import com.nawforce.pkgforce.names.{Name, Names, TypeName} import com.nawforce.pkgforce.parsers.{CLASS_NATURE, INTERFACE_NATURE, Nature} -import com.nawforce.pkgforce.path.{Location, PathLike, PathLocation, UnsafeLocatable} +import com.nawforce.pkgforce.path.{PathLike, UnsafeLocatable} -import java.io.{PrintWriter, StringWriter} -import java.nio.file.Files import scala.collection.immutable.ArraySeq import scala.collection.mutable @@ -58,13 +55,21 @@ trait FieldDeclaration extends DependencyHolder with UnsafeLocatable with Depend val readAccess: Modifier val writeAccess: Modifier - def isStatic: Boolean = modifiers.contains(STATIC_MODIFIER) - def isPrivate: Boolean = modifiers.contains(PRIVATE_MODIFIER) - lazy val isExternallyVisible: Boolean = + def visibility: Option[Modifier] = + modifiers.find(m => ApexModifiers.visibilityModifiers.contains(m)) + + def isExternallyVisible: Boolean = modifiers.exists(FieldDeclaration.externalFieldModifiers.contains) - override def toString: String = - modifiers.map(_.toString).mkString(" ") + " " + typeName.toString + " " + name.toString + def isStatic: Boolean = modifiers.contains(STATIC_MODIFIER) + + override def toString: String = { + (if (modifiers.nonEmpty) + modifiers + .map(_.toString) + .mkString(" ") + " " + else "") + typeName.toString + " " + name.toString + } // Create an SObjectField version of this field def getSObjectStaticField( @@ -248,8 +253,6 @@ object ConstructorDeclaration { trait MethodDeclaration extends DependencyHolder with Dependent with Parameters { val name: Name val modifiers: ArraySeq[Modifier] - lazy val visibility: Option[Modifier] = - modifiers.find(m => ApexModifiers.visibilityModifiers.contains(m)) def typeName: TypeName @@ -266,7 +269,10 @@ trait MethodDeclaration extends DependencyHolder with Dependent with Parameters def isOverride: Boolean = modifiers.contains(OVERRIDE_MODIFIER) def isTestVisible: Boolean = modifiers.contains(TEST_VISIBLE_ANNOTATION) - lazy val isExternallyVisible: Boolean = + def visibility: Option[Modifier] = + modifiers.find(m => ApexModifiers.visibilityModifiers.contains(m)) + + def isExternallyVisible: Boolean = modifiers.exists(MethodDeclaration.externalMethodModifiers.contains) override def toString: String = { @@ -407,15 +413,14 @@ trait TypeDeclaration extends AbstractTypeDeclaration with Dependent with PreReV def isComplete: Boolean - lazy val isExternallyVisible: Boolean = + def isExternallyVisible: Boolean = modifiers.exists(TypeDeclaration.externalTypeModifiers.contains) - lazy val visibility: Modifier = - // We can have more than one visibility modifier, search in priority order - ApexModifiers.visibilityModifiers.find(modifiers.contains).getOrElse(PRIVATE_MODIFIER) - lazy val isAbstract: Boolean = modifiers.contains(ABSTRACT_MODIFIER) - lazy val isVirtual: Boolean = modifiers.contains(VIRTUAL_MODIFIER) - lazy val isExtensible: Boolean = + def visibility: Option[Modifier] = ApexModifiers.visibilityModifiers.find(modifiers.contains) + def isAbstract: Boolean = modifiers.contains(ABSTRACT_MODIFIER) + def isVirtual: Boolean = modifiers.contains(VIRTUAL_MODIFIER) + def isExtensible: Boolean = nature == INTERFACE_NATURE || (nature == CLASS_NATURE && (isAbstract || isVirtual)) + lazy val isFieldConstructed: Boolean = isSObject || isApexPagesComponent lazy val isSObject: Boolean = superClass.contains(TypeNames.SObject) private lazy val isApexPagesComponent: Boolean = superClass.contains(TypeNames.ApexPagesComponent) diff --git a/jvm/src/main/scala/com/nawforce/apexlink/types/synthetic/CustomFieldDeclaration.scala b/jvm/src/main/scala/com/nawforce/apexlink/types/synthetic/CustomFieldDeclaration.scala index 79cabb7ca..82c89e94b 100644 --- a/jvm/src/main/scala/com/nawforce/apexlink/types/synthetic/CustomFieldDeclaration.scala +++ b/jvm/src/main/scala/com/nawforce/apexlink/types/synthetic/CustomFieldDeclaration.scala @@ -30,8 +30,7 @@ abstract class CustomField( override val modifiers: ArraySeq[Modifier] = CustomField.getModifiers(asStatic) override val readAccess: Modifier = PUBLIC_MODIFIER override val writeAccess: Modifier = PUBLIC_MODIFIER - override def isStatic: Boolean = asStatic - override def isPrivate: Boolean = false + override val isStatic: Boolean = asStatic } object CustomField { diff --git a/jvm/src/main/scala/com/nawforce/apexlink/types/synthetic/CustomMethodDeclaration.scala b/jvm/src/main/scala/com/nawforce/apexlink/types/synthetic/CustomMethodDeclaration.scala index 745a5e16b..45d70ccb0 100644 --- a/jvm/src/main/scala/com/nawforce/apexlink/types/synthetic/CustomMethodDeclaration.scala +++ b/jvm/src/main/scala/com/nawforce/apexlink/types/synthetic/CustomMethodDeclaration.scala @@ -38,7 +38,7 @@ final case class CustomMethodDeclaration( override val modifiers: ArraySeq[Modifier] = CustomMethodDeclaration.getModifiers(asStatic) override val hasBlock: Boolean = false - override lazy val isStatic: Boolean = asStatic + override val isStatic: Boolean = asStatic def summary: MethodSummary = { MethodSummary( diff --git a/jvm/src/test/scala/com/nawforce/apexlink/cst/PropertyTest.scala b/jvm/src/test/scala/com/nawforce/apexlink/cst/PropertyTest.scala index dac4596b1..67eb64614 100644 --- a/jvm/src/test/scala/com/nawforce/apexlink/cst/PropertyTest.scala +++ b/jvm/src/test/scala/com/nawforce/apexlink/cst/PropertyTest.scala @@ -16,7 +16,6 @@ package com.nawforce.apexlink.cst import com.nawforce.apexlink.TestHelper import com.nawforce.apexlink.types.apex.ApexClassDeclaration -import com.nawforce.apexlink.types.core.TypeDeclaration import com.nawforce.pkgforce.modifiers._ import com.nawforce.pkgforce.names.Name import org.scalatest.funsuite.AnyFunSuite @@ -101,9 +100,9 @@ class PropertyTest extends AnyFunSuite with TestHelper { ) } - test("Default property access private") { + test("Default property access empty") { val property = typeDeclaration("public class Dummy {String foo{get; set;}}").fields.head - assert(property.modifiers == ArraySeq(PRIVATE_MODIFIER)) + assert(property.modifiers == ArraySeq()) assert(property.readAccess == PRIVATE_MODIFIER) assert(property.writeAccess == property.readAccess) assert(!hasIssues) @@ -237,7 +236,7 @@ class PropertyTest extends AnyFunSuite with TestHelper { test("Static property") { val property = typeDeclaration("public class Dummy {static String foo{get; set;}}").fields.head - assert(property.modifiers == ArraySeq(PRIVATE_MODIFIER, STATIC_MODIFIER)) + assert(property.modifiers == ArraySeq(STATIC_MODIFIER)) assert(property.readAccess == PRIVATE_MODIFIER) assert(property.writeAccess == property.readAccess) assert(!hasIssues) @@ -245,7 +244,7 @@ class PropertyTest extends AnyFunSuite with TestHelper { test("Final property") { val property = typeDeclaration("public class Dummy {final String foo{get; set;}}").fields.head - assert(property.modifiers == ArraySeq(PRIVATE_MODIFIER, FINAL_MODIFIER)) + assert(property.modifiers == ArraySeq(FINAL_MODIFIER)) assert(property.readAccess == PRIVATE_MODIFIER) assert(property.writeAccess == property.readAccess) assert(!hasIssues) @@ -295,7 +294,7 @@ class PropertyTest extends AnyFunSuite with TestHelper { test("AuraEnabled property") { val property = typeDeclaration("public class Dummy {@AuraEnabled String foo{get; set;}}").fields.head - assert(property.modifiers == ArraySeq(PRIVATE_MODIFIER, AURA_ENABLED_ANNOTATION)) + assert(property.modifiers == ArraySeq(AURA_ENABLED_ANNOTATION)) assert(property.readAccess == PRIVATE_MODIFIER) assert(property.writeAccess == property.readAccess) assert(!hasIssues) @@ -304,7 +303,7 @@ class PropertyTest extends AnyFunSuite with TestHelper { test("Deprecated property") { val property = typeDeclaration("public class Dummy {@Deprecated String foo{get; set;}}").fields.head - assert(property.modifiers == ArraySeq(PRIVATE_MODIFIER, DEPRECATED_ANNOTATION)) + assert(property.modifiers == ArraySeq(DEPRECATED_ANNOTATION)) assert(property.readAccess == PRIVATE_MODIFIER) assert(property.writeAccess == property.readAccess) assert(!hasIssues) @@ -313,7 +312,7 @@ class PropertyTest extends AnyFunSuite with TestHelper { test("InvocableVariable property") { val property = typeDeclaration("public class Dummy {@InvocableVariable String foo{get; set;}}").fields.head - assert(property.modifiers == ArraySeq(PRIVATE_MODIFIER, INVOCABLE_VARIABLE_ANNOTATION)) + assert(property.modifiers == ArraySeq(INVOCABLE_VARIABLE_ANNOTATION)) assert(property.readAccess == PRIVATE_MODIFIER) assert(property.writeAccess == property.readAccess) assert(!hasIssues) @@ -322,7 +321,7 @@ class PropertyTest extends AnyFunSuite with TestHelper { test("TestVisible property") { val property = typeDeclaration("public class Dummy {@TestVisible String foo{get; set;}}").fields.head - assert(property.modifiers == ArraySeq(PRIVATE_MODIFIER, TEST_VISIBLE_ANNOTATION)) + assert(property.modifiers == ArraySeq(TEST_VISIBLE_ANNOTATION)) assert(property.readAccess == PRIVATE_MODIFIER) assert(property.writeAccess == property.readAccess) assert(!hasIssues) @@ -333,7 +332,7 @@ class PropertyTest extends AnyFunSuite with TestHelper { typeDeclaration( "public class Dummy {@SuppressWarnings('PMD') String foo{get; set;}}" ).fields.head - assert(property.modifiers == ArraySeq(PRIVATE_MODIFIER, SUPPRESS_WARNINGS_ANNOTATION_PMD)) + assert(property.modifiers == ArraySeq(SUPPRESS_WARNINGS_ANNOTATION_PMD)) assert(property.readAccess == PRIVATE_MODIFIER) assert(property.writeAccess == property.readAccess) assert(!hasIssues) @@ -342,7 +341,7 @@ class PropertyTest extends AnyFunSuite with TestHelper { test("Bad annotation property") { val property = typeDeclaration("public class Dummy {@TestSetup String foo{get; set;}}").fields.head - assert(property.modifiers == ArraySeq(PRIVATE_MODIFIER)) + assert(property.modifiers == ArraySeq()) assert(property.readAccess == PRIVATE_MODIFIER) assert(property.writeAccess == property.readAccess) assert( @@ -356,7 +355,7 @@ class PropertyTest extends AnyFunSuite with TestHelper { typeDeclaration( "public class Dummy {@TestVisible @TestVisible String foo{get; set;}}" ).fields.head - assert(property.modifiers == ArraySeq(PRIVATE_MODIFIER, TEST_VISIBLE_ANNOTATION)) + assert(property.modifiers == ArraySeq(TEST_VISIBLE_ANNOTATION)) assert(property.readAccess == PRIVATE_MODIFIER) assert(property.writeAccess == property.readAccess) assert( diff --git a/jvm/src/test/scala/com/nawforce/apexlink/pkg/CompletionProviderTest.scala b/jvm/src/test/scala/com/nawforce/apexlink/pkg/CompletionProviderTest.scala index 1a140ca45..6f64a6a04 100644 --- a/jvm/src/test/scala/com/nawforce/apexlink/pkg/CompletionProviderTest.scala +++ b/jvm/src/test/scala/com/nawforce/apexlink/pkg/CompletionProviderTest.scala @@ -22,21 +22,47 @@ import org.scalatest.funsuite.AnyFunSuite class CompletionProviderTest extends AnyFunSuite with TestHelper { + private val bodyContent = """ + |global void methodGlobal(){} + |public String methodA(){} + |public String methodB(String a, String b){} + |protected void methodProtected(){} + |private String methodPrivate(){} + |Integer methodImplicitPrivate(){} + | + |global static void methodGlobalStatic(){} + |public static String methodStatic(){} + |private static String methodStaticPrivate(){} + |static Integer methodStaticImplicitPrivate(){} + | + |global String myGlobalField; + |public String myField; + |protected String myProtectedField; + |private String myPrivateField; + |String myImplicitPrivateField; + | + |global static String myGlobalStaticField; + |public static String myStaticField; + |private static String myPrivateStaticField; + |static String myImplicitPrivateStaticField; + | + |global class MyGlobalInner{}; + |public class MyInner{}; + |private interface MyPrivateInner{}; + |interface MyImplicitPrivateInner{}; + |""".stripMargin.replaceAll("\r\n", "\n") + + private val dummyContent = s"""global virtual class Dummy { + |$bodyContent + |}""".stripMargin.replaceAll("\r\n", "\n") + test("Internal Completion") { FileSystemHelper.run(Map()) { root: PathLike => val org = createOrg(root) val path = root.join("Completion.cls") val content = - """public class Dummy { public void someMethod() {m} - |public String methodA(){} - |public String methodB(String a, String b){} - |public static String methodStatic(){} - |private String methodPrivate(){} - |public String myField; - |public static String myStaticField; - |private String myPrivateField; - |public class MyInner{}; - |private interface MyPrivateInner{}; + s"""public virtual class Dummy { public void someMethod() {m} + |$bodyContent |}""".stripMargin.replaceAll("\r\n", "\n") val offset = content.split('\n').head.length - 1 val completions = org.getCompletionItemsInternal(path, line = 1, offset, content) @@ -46,27 +72,69 @@ class CompletionProviderTest extends AnyFunSuite with TestHelper { .filterNot(_.kind == "Keyword") .toSet == Set( + CompletionItemLink("methodGlobal()", "Method", "global void methodGlobal()"), CompletionItemLink( "methodB(a, b)", "Method", "public System.String methodB(System.String a, System.String b)" ), CompletionItemLink("methodA()", "Method", "public System.String methodA()"), + CompletionItemLink("methodProtected()", "Method", "protected void methodProtected()"), CompletionItemLink( "methodPrivate()", "Method", "private System.String methodPrivate()" ), + CompletionItemLink( + "methodImplicitPrivate()", + "Method", + "System.Integer methodImplicitPrivate()" + ), + CompletionItemLink( + "methodGlobalStatic()", + "Method", + "global static void methodGlobalStatic()" + ), CompletionItemLink( "methodStatic()", "Method", "public static System.String methodStatic()" ), + CompletionItemLink( + "methodStaticPrivate()", + "Method", + "private static System.String methodStaticPrivate()" + ), + CompletionItemLink( + "methodStaticImplicitPrivate()", + "Method", + "static System.Integer methodStaticImplicitPrivate()" + ), + CompletionItemLink("myGlobalField", "Field", "global String myGlobalField"), CompletionItemLink("myField", "Field", "public String myField"), - CompletionItemLink("myStaticField", "Field", "public static String myStaticField"), + CompletionItemLink("myProtectedField", "Field", "protected String myProtectedField"), CompletionItemLink("myPrivateField", "Field", "private String myPrivateField"), + CompletionItemLink("myImplicitPrivateField", "Field", "String myImplicitPrivateField"), + CompletionItemLink( + "myGlobalStaticField", + "Field", + "global static String myGlobalStaticField" + ), + CompletionItemLink("myStaticField", "Field", "public static String myStaticField"), + CompletionItemLink( + "myPrivateStaticField", + "Field", + "private static String myPrivateStaticField" + ), + CompletionItemLink( + "myImplicitPrivateStaticField", + "Field", + "static String myImplicitPrivateStaticField" + ), + CompletionItemLink("MyGlobalInner", "Class", "global"), CompletionItemLink("MyInner", "Class", "public"), - CompletionItemLink("MyPrivateInner", "Interface", "private") + CompletionItemLink("MyPrivateInner", "Interface", "private"), + CompletionItemLink("MyImplicitPrivateInner", "Interface", "") ) ) } @@ -77,16 +145,8 @@ class CompletionProviderTest extends AnyFunSuite with TestHelper { val org = createOrg(root) val path = root.join("Completion.cls") val content = - """public class Dummy { public void someMethod() {m} - |public String methodA(){} - |public String methodB(String a, String b){} - |public static String methodStatic(){} - |private String methodPrivate(){} - |public String myField; - |public static String myStaticField; - |private String myPrivateField; - |public class MyInner{}; - |private interface MyPrivateInner{}; + s"""public virtual class Dummy { public void someMethod() {m} + |$bodyContent |}""".stripMargin.replaceAll("\r\n", "\n") val offset = content.split('\n').head.length - 1 val completions = org.getCompletionItemsInternal(path, line = 1, offset, content) @@ -96,49 +156,76 @@ class CompletionProviderTest extends AnyFunSuite with TestHelper { .filterNot(_.kind == "Keyword") .toSet == Set( + CompletionItemLink("methodGlobal()", "Method", "global void methodGlobal()"), CompletionItemLink( "methodB(a, b)", "Method", "public System.String methodB(System.String a, System.String b)" ), CompletionItemLink("methodA()", "Method", "public System.String methodA()"), + CompletionItemLink("methodProtected()", "Method", "protected void methodProtected()"), CompletionItemLink( "methodPrivate()", "Method", "private System.String methodPrivate()" ), + CompletionItemLink( + "methodImplicitPrivate()", + "Method", + "System.Integer methodImplicitPrivate()" + ), + CompletionItemLink( + "methodGlobalStatic()", + "Method", + "global static void methodGlobalStatic()" + ), CompletionItemLink( "methodStatic()", "Method", "public static System.String methodStatic()" ), + CompletionItemLink( + "methodStaticPrivate()", + "Method", + "private static System.String methodStaticPrivate()" + ), + CompletionItemLink( + "methodStaticImplicitPrivate()", + "Method", + "static System.Integer methodStaticImplicitPrivate()" + ), + CompletionItemLink("myGlobalField", "Field", "global String myGlobalField"), CompletionItemLink("myField", "Field", "public String myField"), - CompletionItemLink("myStaticField", "Field", "public static String myStaticField"), + CompletionItemLink("myProtectedField", "Field", "protected String myProtectedField"), CompletionItemLink("myPrivateField", "Field", "private String myPrivateField"), + CompletionItemLink("myImplicitPrivateField", "Field", "String myImplicitPrivateField"), + CompletionItemLink( + "myGlobalStaticField", + "Field", + "global static String myGlobalStaticField" + ), + CompletionItemLink("myStaticField", "Field", "public static String myStaticField"), + CompletionItemLink( + "myPrivateStaticField", + "Field", + "private static String myPrivateStaticField" + ), + CompletionItemLink( + "myImplicitPrivateStaticField", + "Field", + "static String myImplicitPrivateStaticField" + ), + CompletionItemLink("MyGlobalInner", "Class", "global"), CompletionItemLink("MyInner", "Class", "public"), - CompletionItemLink("MyPrivateInner", "Interface", "private") + CompletionItemLink("MyPrivateInner", "Interface", "private"), + CompletionItemLink("MyImplicitPrivateInner", "Interface", "") ) ) } } test("Instance Completions") { - FileSystemHelper.run( - Map( - "Dummy.cls" -> - """public class Dummy { - |public String methodA(){} - |public String methodB(String a, String b){} - |public static String methodStatic(){} - |private String methodPrivate(){} - |public String myField; - |public static String myStaticField; - |private String myPrivateField; - |public class MyInner{}; - |private interface MyPrivateInner{}; - |}""".stripMargin - ) - ) { root: PathLike => + FileSystemHelper.run(Map("Dummy.cls" -> dummyContent)) { root: PathLike => val org = createOrg(root) val path = root.join("Completion.cls") val content = "public class Completion { public Completion() {String a = new Dummy().m" @@ -147,35 +234,49 @@ class CompletionProviderTest extends AnyFunSuite with TestHelper { .getCompletionItemsInternal(path, line = 1, offset = content.length, content) .toSet == Set( + CompletionItemLink("methodGlobal()", "Method", "global void methodGlobal()"), CompletionItemLink( "methodB(a, b)", "Method", "public System.String methodB(System.String a, System.String b)" ), CompletionItemLink("methodA()", "Method", "public System.String methodA()"), + CompletionItemLink("myGlobalField", "Field", "global String myGlobalField"), CompletionItemLink("myField", "Field", "public String myField") ) ) } } - test("Static Completions") { - FileSystemHelper.run( - Map( - "Dummy.cls" -> - """public class Dummy { - |public String methodA(){} - |public String methodB(String a, String b){} - |public static String methodStatic(){} - |private String methodPrivate(){} - |public String myField; - |public static String myStaticField; - |private String myPrivateField; - |public class MyInner{}; - |private interface MyPrivateInner{}; - |}""".stripMargin + test("Instance Completions (extending)") { + FileSystemHelper.run(Map("Dummy.cls" -> dummyContent)) { root: PathLike => + val org = createOrg(root) + val path = root.join("Completion.cls") + val content = + "public class Completion extends Dummy { public Completion() {String a = new Dummy().m" + assert( + org + .getCompletionItemsInternal(path, line = 1, offset = content.length, content) + .toSet == + Set( + CompletionItemLink("methodGlobal()", "Method", "global void methodGlobal()"), + CompletionItemLink( + "methodB(a, b)", + "Method", + "public System.String methodB(System.String a, System.String b)" + ), + CompletionItemLink("methodA()", "Method", "public System.String methodA()"), + CompletionItemLink("methodProtected()", "Method", "protected void methodProtected()"), + CompletionItemLink("myGlobalField", "Field", "global String myGlobalField"), + CompletionItemLink("myField", "Field", "public String myField"), + CompletionItemLink("myProtectedField", "Field", "protected String myProtectedField") + ) ) - ) { root: PathLike => + } + } + + test("Static Completions") { + FileSystemHelper.run(Map("Dummy.cls" -> dummyContent)) { root: PathLike => val org = createOrg(root) val path = root.join("Completion.cls") val content = "public class Completion { public Completion() {String a = Dummy.m" @@ -184,12 +285,23 @@ class CompletionProviderTest extends AnyFunSuite with TestHelper { .getCompletionItemsInternal(path, line = 1, offset = content.length, content) .toSet == Set( + CompletionItemLink( + "methodGlobalStatic()", + "Method", + "global static void methodGlobalStatic()" + ), CompletionItemLink( "methodStatic()", "Method", "public static System.String methodStatic()" ), + CompletionItemLink( + "myGlobalStaticField", + "Field", + "global static String myGlobalStaticField" + ), CompletionItemLink("myStaticField", "Field", "public static String myStaticField"), + CompletionItemLink("MyGlobalInner", "Class", "global"), CompletionItemLink("MyInner", "Class", "public") ) ) @@ -197,22 +309,7 @@ class CompletionProviderTest extends AnyFunSuite with TestHelper { } test("Instance Completions (in statement)") { - FileSystemHelper.run( - Map( - "Dummy.cls" -> - """public class Dummy { - |public String methodA(){} - |public String methodB(String a, String b){} - |public static String methodStatic(){} - |private String methodPrivate(){} - |public String myField; - |public static String myStaticField; - |private String myPrivateField; - |public class MyInner{}; - |private interface MyPrivateInner{}; - |}""".stripMargin - ) - ) { root: PathLike => + FileSystemHelper.run(Map("Dummy.cls" -> dummyContent)) { root: PathLike => val org = createOrg(root) val path = root.join("Completion.cls") val content = "public class Completion { public Completion() {Dummy a; if ( a.m" @@ -221,12 +318,14 @@ class CompletionProviderTest extends AnyFunSuite with TestHelper { .getCompletionItemsInternal(path, line = 1, offset = content.length, content) .toSet == Set( + CompletionItemLink("methodGlobal()", "Method", "global void methodGlobal()"), CompletionItemLink( "methodB(a, b)", "Method", "public System.String methodB(System.String a, System.String b)" ), CompletionItemLink("methodA()", "Method", "public System.String methodA()"), + CompletionItemLink("myGlobalField", "Field", "global String myGlobalField"), CompletionItemLink("myField", "Field", "public String myField") ) ) @@ -234,22 +333,7 @@ class CompletionProviderTest extends AnyFunSuite with TestHelper { } test("Instance Completions (no context)") { - FileSystemHelper.run( - Map( - "Dummy.cls" -> - """public class Dummy { - |public String methodA(){} - |public String methodB(String a, String b){} - |public static String methodStatic(){} - |private String methodPrivate(){} - |public String myField; - |public static String myStaticField; - |private String myPrivateField; - |public class MyInner{}; - |private interface MyPrivateInner{}; - |}""".stripMargin - ) - ) { root: PathLike => + FileSystemHelper.run(Map("Dummy.cls" -> dummyContent)) { root: PathLike => val org = createOrg(root) val path = root.join("Completion.cls") val content = "public class Completion { public Completion() {String a = new Dummy()." @@ -258,6 +342,7 @@ class CompletionProviderTest extends AnyFunSuite with TestHelper { .getCompletionItemsInternal(path, line = 1, offset = content.length, content) .toSet == Set( + CompletionItemLink("methodGlobal()", "Method", "global void methodGlobal()"), CompletionItemLink("methodA()", "Method", "public System.String methodA()"), CompletionItemLink( "methodB(a, b)", @@ -272,6 +357,7 @@ class CompletionProviderTest extends AnyFunSuite with TestHelper { "Method", "public virtual System.Boolean equals(Object other)" ), + CompletionItemLink("myGlobalField", "Field", "global String myGlobalField"), CompletionItemLink("myField", "Field", "public String myField") ) ) @@ -662,22 +748,7 @@ class CompletionProviderTest extends AnyFunSuite with TestHelper { } test("Triggers Static Completions") { - FileSystemHelper.run( - Map( - "Dummy.cls" -> - """public class Dummy { - |public String methodA(){} - |public String methodB(String a, String b){} - |public static String methodStatic(){} - |private String methodPrivate(){} - |public String myField; - |public static String myStaticField; - |private String myPrivateField; - |public class MyInner{}; - |private interface MyPrivateInner{}; - |}""".stripMargin - ) - ) { root: PathLike => + FileSystemHelper.run(Map("Dummy.cls" -> dummyContent)) { root: PathLike => val org = createOrg(root) val path = root.join("Completion.trigger") val content = "trigger Completion on Account(before insert) { Dummy.m" @@ -686,12 +757,23 @@ class CompletionProviderTest extends AnyFunSuite with TestHelper { .getCompletionItemsInternal(path, line = 1, offset = content.length, content) .toSet == Set( + CompletionItemLink( + "methodGlobalStatic()", + "Method", + "global static void methodGlobalStatic()" + ), CompletionItemLink( "methodStatic()", "Method", "public static System.String methodStatic()" ), + CompletionItemLink( + "myGlobalStaticField", + "Field", + "global static String myGlobalStaticField" + ), CompletionItemLink("myStaticField", "Field", "public static String myStaticField"), + CompletionItemLink("MyGlobalInner", "Class", "global"), CompletionItemLink("MyInner", "Class", "public") ) ) diff --git a/shared/src/main/scala/com/nawforce/pkgforce/modifiers/FieldModifiers.scala b/shared/src/main/scala/com/nawforce/pkgforce/modifiers/FieldModifiers.scala index 47f147d9e..616f6ea90 100644 --- a/shared/src/main/scala/com/nawforce/pkgforce/modifiers/FieldModifiers.scala +++ b/shared/src/main/scala/com/nawforce/pkgforce/modifiers/FieldModifiers.scala @@ -87,8 +87,6 @@ object FieldModifiers { ) { logger.logError(idContext, "Webservice fields must be global") GLOBAL_MODIFIER +: mods.diff(visibilityModifiers) - } else if (mods.intersect(visibilityModifiers).isEmpty) { - PRIVATE_MODIFIER +: mods } else { mods } diff --git a/shared/src/main/scala/com/nawforce/pkgforce/modifiers/Modifier.scala b/shared/src/main/scala/com/nawforce/pkgforce/modifiers/Modifier.scala index 07565d5b0..1f2b8c3de 100644 --- a/shared/src/main/scala/com/nawforce/pkgforce/modifiers/Modifier.scala +++ b/shared/src/main/scala/com/nawforce/pkgforce/modifiers/Modifier.scala @@ -27,8 +27,8 @@ import scala.collection.compat.immutable.ArraySeq sealed abstract class Modifier( final val name: String, - val order: Integer = 0, - val methodOrder: Integer = 0 + val order: Int = 0, + val methodOrder: Int = 0 ) { override def toString: String = name } diff --git a/shared/src/test/scala/com/nawforce/pkgforce/modifiers/FieldModifierTest.scala b/shared/src/test/scala/com/nawforce/pkgforce/modifiers/FieldModifierTest.scala index d595ba066..894a99b9e 100644 --- a/shared/src/test/scala/com/nawforce/pkgforce/modifiers/FieldModifierTest.scala +++ b/shared/src/test/scala/com/nawforce/pkgforce/modifiers/FieldModifierTest.scala @@ -71,8 +71,8 @@ class FieldModifierTest extends AnyFunSuite { } } - test("Default field access private") { - assert(legalFieldAccess(ArraySeq(), ArraySeq(PRIVATE_MODIFIER))) + test("Default field access empty") { + assert(legalFieldAccess(ArraySeq(), ArraySeq())) } test("Private field") { @@ -105,9 +105,7 @@ class FieldModifierTest extends AnyFunSuite { } test("Transient field") { - assert( - legalFieldAccess(ArraySeq(TRANSIENT_MODIFIER), ArraySeq(PRIVATE_MODIFIER, TRANSIENT_MODIFIER)) - ) + assert(legalFieldAccess(ArraySeq(TRANSIENT_MODIFIER), ArraySeq(TRANSIENT_MODIFIER))) } test("Transient public field") { @@ -120,7 +118,7 @@ class FieldModifierTest extends AnyFunSuite { } test("Static field") { - assert(legalFieldAccess(ArraySeq(STATIC_MODIFIER), ArraySeq(PRIVATE_MODIFIER, STATIC_MODIFIER))) + assert(legalFieldAccess(ArraySeq(STATIC_MODIFIER), ArraySeq(STATIC_MODIFIER))) } test("Static public field") { @@ -133,7 +131,7 @@ class FieldModifierTest extends AnyFunSuite { } test("Final field") { - assert(legalFieldAccess(ArraySeq(FINAL_MODIFIER), ArraySeq(PRIVATE_MODIFIER, FINAL_MODIFIER))) + assert(legalFieldAccess(ArraySeq(FINAL_MODIFIER), ArraySeq(FINAL_MODIFIER))) } test("Final public field") { @@ -154,46 +152,31 @@ class FieldModifierTest extends AnyFunSuite { } test("AuraEnabled field") { - assert( - legalFieldAccess( - ArraySeq(AURA_ENABLED_ANNOTATION), - ArraySeq(PRIVATE_MODIFIER, AURA_ENABLED_ANNOTATION) - ) - ) + assert(legalFieldAccess(ArraySeq(AURA_ENABLED_ANNOTATION), ArraySeq(AURA_ENABLED_ANNOTATION))) } test("Deprecated field") { - assert( - legalFieldAccess( - ArraySeq(DEPRECATED_ANNOTATION), - ArraySeq(PRIVATE_MODIFIER, DEPRECATED_ANNOTATION) - ) - ) + assert(legalFieldAccess(ArraySeq(DEPRECATED_ANNOTATION), ArraySeq(DEPRECATED_ANNOTATION))) } test("InvocableVariable field") { assert( legalFieldAccess( ArraySeq(INVOCABLE_VARIABLE_ANNOTATION), - ArraySeq(PRIVATE_MODIFIER, INVOCABLE_VARIABLE_ANNOTATION) + ArraySeq(INVOCABLE_VARIABLE_ANNOTATION) ) ) } test("TestVisible field") { - assert( - legalFieldAccess( - ArraySeq(TEST_VISIBLE_ANNOTATION), - ArraySeq(PRIVATE_MODIFIER, TEST_VISIBLE_ANNOTATION) - ) - ) + assert(legalFieldAccess(ArraySeq(TEST_VISIBLE_ANNOTATION), ArraySeq(TEST_VISIBLE_ANNOTATION))) } test("SuppressWarnings PMD field") { assert( legalFieldAccess( ArraySeq(SUPPRESS_WARNINGS_ANNOTATION_PMD), - ArraySeq(PRIVATE_MODIFIER, SUPPRESS_WARNINGS_ANNOTATION_PMD) + ArraySeq(SUPPRESS_WARNINGS_ANNOTATION_PMD) ) ) } @@ -202,7 +185,7 @@ class FieldModifierTest extends AnyFunSuite { assert( legalFieldAccess( ArraySeq(SUPPRESS_WARNINGS_ANNOTATION_UNUSED), - ArraySeq(PRIVATE_MODIFIER, SUPPRESS_WARNINGS_ANNOTATION_UNUSED) + ArraySeq(SUPPRESS_WARNINGS_ANNOTATION_UNUSED) ) ) } @@ -296,7 +279,7 @@ class FieldModifierTest extends AnyFunSuite { } test("Inner Default field access private") { - assert(innerLegalFieldAccess(ArraySeq(), ArraySeq(PRIVATE_MODIFIER))) + assert(innerLegalFieldAccess(ArraySeq(), ArraySeq())) } test("Inner Private field") { @@ -329,12 +312,7 @@ class FieldModifierTest extends AnyFunSuite { } test("Inner Transient field") { - assert( - innerLegalFieldAccess( - ArraySeq(TRANSIENT_MODIFIER), - ArraySeq(PRIVATE_MODIFIER, TRANSIENT_MODIFIER) - ) - ) + assert(innerLegalFieldAccess(ArraySeq(TRANSIENT_MODIFIER), ArraySeq(TRANSIENT_MODIFIER))) } test("Inner Transient public field") { @@ -360,13 +338,10 @@ class FieldModifierTest extends AnyFunSuite { ) ) ) - } test("Inner Final field") { - assert( - innerLegalFieldAccess(ArraySeq(FINAL_MODIFIER), ArraySeq(PRIVATE_MODIFIER, FINAL_MODIFIER)) - ) + assert(innerLegalFieldAccess(ArraySeq(FINAL_MODIFIER), ArraySeq(FINAL_MODIFIER))) } test("Inner Final public field") { @@ -384,37 +359,26 @@ class FieldModifierTest extends AnyFunSuite { test("Inner AuraEnabled field") { assert( - innerLegalFieldAccess( - ArraySeq(AURA_ENABLED_ANNOTATION), - ArraySeq(PRIVATE_MODIFIER, AURA_ENABLED_ANNOTATION) - ) + innerLegalFieldAccess(ArraySeq(AURA_ENABLED_ANNOTATION), ArraySeq(AURA_ENABLED_ANNOTATION)) ) } test("Inner Deprecated field") { - assert( - innerLegalFieldAccess( - ArraySeq(DEPRECATED_ANNOTATION), - ArraySeq(PRIVATE_MODIFIER, DEPRECATED_ANNOTATION) - ) - ) + assert(innerLegalFieldAccess(ArraySeq(DEPRECATED_ANNOTATION), ArraySeq(DEPRECATED_ANNOTATION))) } test("Inner InvocableVariable field") { assert( innerLegalFieldAccess( ArraySeq(INVOCABLE_VARIABLE_ANNOTATION), - ArraySeq(PRIVATE_MODIFIER, INVOCABLE_VARIABLE_ANNOTATION) + ArraySeq(INVOCABLE_VARIABLE_ANNOTATION) ) ) } test("Inner TestVisible field") { assert( - innerLegalFieldAccess( - ArraySeq(TEST_VISIBLE_ANNOTATION), - ArraySeq(PRIVATE_MODIFIER, TEST_VISIBLE_ANNOTATION) - ) + innerLegalFieldAccess(ArraySeq(TEST_VISIBLE_ANNOTATION), ArraySeq(TEST_VISIBLE_ANNOTATION)) ) } @@ -422,7 +386,7 @@ class FieldModifierTest extends AnyFunSuite { assert( innerLegalFieldAccess( ArraySeq(SUPPRESS_WARNINGS_ANNOTATION_PMD), - ArraySeq(PRIVATE_MODIFIER, SUPPRESS_WARNINGS_ANNOTATION_PMD) + ArraySeq(SUPPRESS_WARNINGS_ANNOTATION_PMD) ) ) } @@ -431,7 +395,7 @@ class FieldModifierTest extends AnyFunSuite { assert( innerLegalFieldAccess( ArraySeq(SUPPRESS_WARNINGS_ANNOTATION_UNUSED), - ArraySeq(PRIVATE_MODIFIER, SUPPRESS_WARNINGS_ANNOTATION_UNUSED) + ArraySeq(SUPPRESS_WARNINGS_ANNOTATION_UNUSED) ) ) } From 12267dbc641401708db18969a970ac08d9594a1c Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Mon, 23 Dec 2024 11:09:05 +0000 Subject: [PATCH 2/2] Explicitly request sbt on actions --- .github/workflows/Build.yml | 2 ++ .github/workflows/BuildCrossPlatform.yml | 2 ++ .github/workflows/BuildWin.yml | 2 ++ .github/workflows/Publish.yml | 2 ++ .github/workflows/UnitTest.yml | 2 ++ 5 files changed, 10 insertions(+) diff --git a/.github/workflows/Build.yml b/.github/workflows/Build.yml index 08d870705..292e179dc 100644 --- a/.github/workflows/Build.yml +++ b/.github/workflows/Build.yml @@ -20,6 +20,8 @@ jobs: java-version: 8 cache: "sbt" + - uses: sbt/setup-sbt@v1 + - uses: actions/setup-node@v4 with: node-version: 20 diff --git a/.github/workflows/BuildCrossPlatform.yml b/.github/workflows/BuildCrossPlatform.yml index d61128991..8ceb0bdb5 100644 --- a/.github/workflows/BuildCrossPlatform.yml +++ b/.github/workflows/BuildCrossPlatform.yml @@ -27,6 +27,8 @@ jobs: distribution: "temurin" java-version: ${{ matrix.java_version }} + - uses: sbt/setup-sbt@v1 + - uses: actions/setup-node@v4 with: node-version: 20 diff --git a/.github/workflows/BuildWin.yml b/.github/workflows/BuildWin.yml index fd3e9630c..f16dd32de 100644 --- a/.github/workflows/BuildWin.yml +++ b/.github/workflows/BuildWin.yml @@ -18,6 +18,8 @@ jobs: java-version: 8 cache: "sbt" + - uses: sbt/setup-sbt@v1 + - uses: actions/setup-node@v4 with: node-version: 20 diff --git a/.github/workflows/Publish.yml b/.github/workflows/Publish.yml index 87ef01ab3..a3c717a67 100644 --- a/.github/workflows/Publish.yml +++ b/.github/workflows/Publish.yml @@ -35,6 +35,8 @@ jobs: distribution: "temurin" java-version: 8 + - uses: sbt/setup-sbt@v1 + - uses: actions/setup-node@v4 with: node-version: 20 diff --git a/.github/workflows/UnitTest.yml b/.github/workflows/UnitTest.yml index 0a5ebefb6..e151a89e6 100644 --- a/.github/workflows/UnitTest.yml +++ b/.github/workflows/UnitTest.yml @@ -16,6 +16,8 @@ jobs: java-version: 8 cache: "sbt" + - uses: sbt/setup-sbt@v1 + - uses: actions/setup-node@v4 with: node-version: 20