Skip to content

Commit 6166aba

Browse files
authored
Merge pull request #72 from salesforce/add-basque
add Basque language support
2 parents 5fcd14e + ae60830 commit 6166aba

20 files changed

+2889
-189
lines changed

pom.xml

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
<groupId>com.salesforce.grammaticus</groupId>
55
<artifactId>grammaticus</artifactId>
6-
<version>1.2.32-SNAPSHOT</version>
6+
<version>1.3.0-SNAPSHOT</version>
77
<packaging>jar</packaging>
88

99
<name>Grammaticus</name>
@@ -41,12 +41,9 @@
4141
</developers>
4242

4343
<properties>
44-
<maven.compiler.release>11</maven.compiler.release>
44+
<java.version>17</java.version>
45+
<maven.compiler.release>17</maven.compiler.release>
4546
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
46-
<icu4j.version>75.1</icu4j.version>
47-
<icu4j-localespi.version>75.1</icu4j-localespi.version>
48-
<picocli.version>4.1.4</picocli.version>
49-
<caffeine.version>2.8.0</caffeine.version>
5047
</properties>
5148

5249
<profiles>
@@ -75,10 +72,11 @@
7572
</plugin>
7673
<plugin>
7774
<artifactId>maven-surefire-plugin</artifactId>
78-
<version>3.0.0-M8</version>
75+
<version>3.2.5</version>
7976
<configuration>
8077
<!-- suppress all loggings for unit test -->
8178
<argLine>@{argLine} -Djava.util.logging.config.file=src/test/resources/logging.properties -Dpolyglot.engine.WarnInterpreterOnly=false</argLine>
79+
<useModulePath>false</useModulePath>
8280
</configuration>
8381
</plugin>
8482
<plugin>
@@ -270,38 +268,64 @@
270268
<dependency>
271269
<groupId>com.google.guava</groupId>
272270
<artifactId>guava</artifactId>
273-
<version>33.4.0-jre</version>
271+
<version>33.4.8-jre</version>
274272
</dependency>
275273

276274
<dependency>
277275
<groupId>junit</groupId>
278276
<artifactId>junit</artifactId>
279-
<version>4.13.1</version>
277+
<version>4.13.2</version>
278+
<scope>test</scope>
279+
</dependency>
280+
281+
<!-- JUnit 5 (Jupiter) and Vintage to keep JUnit 4 tests working -->
282+
<dependency>
283+
<groupId>org.junit.jupiter</groupId>
284+
<artifactId>junit-jupiter-api</artifactId>
285+
<version>5.10.2</version>
286+
<scope>test</scope>
287+
</dependency>
288+
<dependency>
289+
<groupId>org.junit.jupiter</groupId>
290+
<artifactId>junit-jupiter-params</artifactId>
291+
<version>5.10.2</version>
292+
<scope>test</scope>
293+
</dependency>
294+
<dependency>
295+
<groupId>org.junit.jupiter</groupId>
296+
<artifactId>junit-jupiter-engine</artifactId>
297+
<version>5.10.2</version>
298+
<scope>test</scope>
299+
</dependency>
300+
<dependency>
301+
<groupId>org.junit.vintage</groupId>
302+
<artifactId>junit-vintage-engine</artifactId>
303+
<version>5.10.2</version>
280304
<scope>test</scope>
281305
</dependency>
282306

283307
<dependency>
284308
<groupId>com.ibm.icu</groupId>
285309
<artifactId>icu4j</artifactId>
286-
<version>${icu4j.version}</version>
310+
<version>75.1</version>
287311
</dependency>
288312

289313
<dependency>
290314
<groupId>com.ibm.icu</groupId>
291315
<artifactId>icu4j-localespi</artifactId>
292-
<version>${icu4j-localespi.version}</version>
316+
<version>75.1</version>
293317
<optional>true</optional>
294318
</dependency>
295319

296320
<dependency>
297321
<groupId>com.github.ben-manes.caffeine</groupId>
298322
<artifactId>caffeine</artifactId>
299-
<version>${caffeine.version}</version>
323+
<version>3.2.2</version>
300324
</dependency>
301325
<dependency>
302326
<groupId>com.github.ben-manes.caffeine</groupId>
303327
<artifactId>guava</artifactId>
304-
<version>${caffeine.version}</version>
328+
<version>3.1.7</version>
305329
</dependency>
306330

307331
<dependency>
@@ -314,7 +338,7 @@
314338
<dependency>
315339
<groupId>info.picocli</groupId>
316340
<artifactId>picocli</artifactId>
317-
<version>${picocli.version}</version>
341+
<version>4.1.4</version>
318342
<scope>test</scope>
319343
</dependency>
320344
<dependency>

src/main/java/com/force/i18n/LabelUtils.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
import java.util.regex.Matcher;
3333
import java.util.regex.Pattern;
3434

35-
import org.checkerframework.checker.nullness.qual.Nullable;
36-
3735
import com.force.i18n.commons.text.GenericTrieMatcher;
3836
import com.force.i18n.commons.text.GenericTrieMatcher.GenericTrieMatch;
3937
import com.force.i18n.commons.text.TextUtil;
@@ -134,7 +132,7 @@ public String getPublicString(GrammaticalLabelSet labelSet, String section, Stri
134132
* @param grammar XML snippet
135133
* @return a sample dictionary file containing the xml snippet inside the "names" tag
136134
*/
137-
public static String getSampleGrammarFile(@Nullable String grammar) {
135+
public static String getSampleGrammarFile(String grammar) {
138136
if (grammar == null || grammar.isEmpty()) {
139137
return null;
140138
} else {

src/main/java/com/force/i18n/grammar/LanguageCase.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public enum LanguageCase {
5757
ADVERBIAL ("adv", "Adverbial"),
5858
ABESSIVE("abe", "Abessive"),
5959
COMITATIVE("com", "Comitative"),
60+
BENEFACTIVE("be", "Benefactive"),
6061
;
6162

6263
public static final char JSON_ATTR_NAME = 'c';

src/main/java/com/force/i18n/grammar/LanguageDeclension.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,11 +361,57 @@ default NounForm getNounForm(LanguageNumber number, LanguageArticle articleType)
361361
return getApproximateNounForm(number, getDefaultCase(), LanguagePossessive.NONE, articleType);
362362
}
363363

364+
/**
365+
* Canonical noun form used by dictionary fallback copy. For languages with
366+
* specialized concrete forms (e.g., Basque), this returns the appropriate
367+
* enum-backed form to store values against. Defaults to getNounForm.
368+
*/
369+
default NounForm getCanonicalNounForm(LanguageNumber number, LanguageArticle articleType) {
370+
return getNounForm(number, articleType);
371+
}
372+
364373
// Convenience method for retrieving an equivalent nounForm from this declension
365374
default NounForm getNounForm(NounForm nf) {
366375
return getExactNounForm(nf.getNumber(), nf.getCase(), nf.getPossessive(), nf.getArticle());
367376
}
368377

378+
/**
379+
* Hint for label parsing: whether to choose approximate/dynamic noun forms at <b>parse time</b>
380+
* (not at render time) when constructing noun refs from labels.
381+
* <p>
382+
* Rationale: For languages whose inflection is primarily realized by productive rules at render time
383+
* (e.g., generated from a bare stem using case/number/article morphology), the parser should preserve
384+
* the requested attributes (number, case, article) by selecting a dynamic/approximate noun form and
385+
* storing it directly in the tag. This avoids re-deriving or collapsing the author-requested attributes
386+
* later, and prevents double approximation.
387+
* </p>
388+
* <p>
389+
* If this method returns {@code true}, callers retrieving a noun tag's form should use that stored form
390+
* as-is instead of recomputing an approximate form at render time.
391+
* </p>
392+
*/
393+
default boolean shouldApproximateNounFormsAtParseTime() { return false; }
394+
395+
/**
396+
* Optional: Generate a rendered <b>surface</b> (the final, inflected output string) from a
397+
* base/lemma value for the given noun form. Implementations may apply language-specific
398+
* morphology and phonological adjustments (e.g., suffix selection, vowel interaction) based on
399+
* the form's attributes (number, case, article, etc.).
400+
* <p>
401+
* Return {@code null} if surface generation from base is not supported by the declension.
402+
* </p>
403+
*/
404+
default String generateSurfaceFromBase(String base, NounForm form) { return null; }
405+
406+
/**
407+
* Optional: Generate a rendered <b>surface</b> directly from a noun term for the given noun form.
408+
* Default implementation delegates to {@link #generateSurfaceFromBase(String, NounForm)} using the
409+
* term's default/base value.
410+
*/
411+
default String generateSurfaceFromTerm(Noun noun, NounForm form) {
412+
return generateSurfaceFromBase(noun == null ? null : noun.getDefaultString(false), form);
413+
}
414+
369415
/**
370416
* @return the maximum distance to look for modifiers associated with the noun
371417
* For languages without spaces between works, this should be 0

src/main/java/com/force/i18n/grammar/Noun.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ public abstract class Noun extends GrammaticalTerm implements Cloneable {
4242
private final NounType nounType;
4343
private String entityName; // not final for readResolve()
4444
private String pluralAlias; // not final for readResolve()
45-
private LanguageGender gender; // TODO: make final
46-
private LanguageStartsWith startsWith; // TODO: make final
45+
private LanguageGender gender;
46+
private LanguageStartsWith startsWith;
4747
private String access; // not final for readResolve()
4848
private final boolean isStandardField; // specifies whether this label is a standard field or not. For the Rename
4949
private final boolean isCopied; // specifies whether this noun was copied from english (or another fallback language)
@@ -175,10 +175,9 @@ protected boolean equalsValue(Noun n) {
175175
}
176176

177177
@Override
178-
public final boolean equals(Object obj) {
178+
public boolean equals(Object obj) {
179179
if (this == obj) return true;
180-
if (obj instanceof Noun) {
181-
Noun n = (Noun)obj;
180+
if (obj instanceof Noun n) {
182181
return super.equals(n) && equalsAttribute(n) && equalsValue(n);
183182
}
184183
return false;

0 commit comments

Comments
 (0)