Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.helger.jcodemodel.IJFormatter;
import com.helger.jcodemodel.JBlock;
import com.helger.jcodemodel.JCatchBlock;
import com.helger.jcodemodel.JOp;
import com.helger.jcodemodel.vars.JCatchFormalParameter;

public class Redirected {
Expand Down Expand Up @@ -73,6 +74,10 @@ public void generate(IJFormatter arg0) {
jCatchBlock.generate(arg0);
}

public JOp.Precedence operatorPrecedence() {
return jCatchBlock.operatorPrecedence();
}

public JCatchFormalParameter param() {
return jCatchBlock.param();
}
Expand Down
1 change: 1 addition & 0 deletions examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<description>POM module for all the examples modules</description>

<modules>
<module>settings</module>
<module>plugins</module>
</modules>

Expand Down
68 changes: 68 additions & 0 deletions examples/settings/example-settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"indent" : {
"string" : " ",
"tabSize" : 4
},
"parentheses" : {
"global" : "REQUIRED"
},
"wrap" : {
"lineWidth" : 80,
"disabled" : false,
"catchClause" : {
"types" : {
"condition" : "NEVER",
"indent" : 1,
"wrapAfterSep" : true
}
},
"forLoop" : {
"init" : {
"condition" : "NEVER",
"indent" : 1,
"wrapAfterSep" : true
}
},
"method" : {
"type" : {
"condition" : "NEVER",
"indent" : 1
},
"name" : {
"condition" : "NEVER",
"indent" : 1
},
"params" : {
"condition" : "PAST3",
"indent" : 1,
"wrapAfterSep" : true
},
"bracket" : {
"condition" : "NEVER",
"indent" : 0
},
"args" : {
"condition" : "PAST3",
"indent" : 1,
"wrapAfterSep" : true
}
},
"variables" : {
"array" : {
"condition" : "REQUIRED",
"indent" : 1,
"wrapAfterSep" : true
},
"block" : {
"condition" : "REQUIRED",
"indent" : 1,
"wrapAfterSep" : true
},
"field" : {
"condition" : "REQUIRED",
"indent" : 1,
"wrapAfterSep" : true
}
}
}
}
49 changes: 49 additions & 0 deletions examples/settings/example-settings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
indent:
string: " "
tabSize: 4
parentheses:
global: "REQUIRED"
wrap:
lineWidth: 80
disabled: false
catchClause:
types:
condition: "NEVER"
indent: 1
wrapAfterSep: true
forLoop:
init:
condition: "NEVER"
indent: 1
wrapAfterSep: true
method:
type:
condition: "NEVER"
indent: 1
name:
condition: "NEVER"
indent: 1
params:
condition: "PAST3"
indent: 1
wrapAfterSep: true
bracket:
condition: "NEVER"
indent: 0
args:
condition: "PAST3"
indent: 1
wrapAfterSep: true
variables:
array:
condition: "REQUIRED"
indent: 1
wrapAfterSep: true
block:
condition: "REQUIRED"
indent: 1
wrapAfterSep: true
field:
condition: "REQUIRED"
indent: 1
wrapAfterSep: true
38 changes: 38 additions & 0 deletions examples/settings/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and
limitations under the License. -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.helger.jcodemodel</groupId>
<artifactId>examples</artifactId>
<version>4.3.1-SNAPSHOT</version>
</parent>
<groupId>com.helger.jcodemodel.examples</groupId>
<artifactId>settings</artifactId>
<name>LIB Settings Examples</name>
<description>shows setting examples</description>

<properties>
<jackson.version>2.20.1</jackson.version>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.helger.jcodemodel.plugin.generators</groupId>
<artifactId>json</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.helger.jcodemodel.example.settings;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UncheckedIOException;

import org.junit.Test;

import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature;
import com.helger.jcodemodel.writer.FormatterSettings;

/// Actually not a test, but export the default formatter settings so people
/// have an idea of the settings available.
/// The yaml and json files are exported at the project root.
public class ExportSettingsTest {

@Test
public void writeYaml() {
FormatterSettings export = new FormatterSettings();

YAMLFactory f =
new YAMLFactory()
.disable(Feature.WRITE_DOC_START_MARKER);
ObjectMapper om = new ObjectMapper(f);

File out = new File("example-settings.yaml");
try (FileWriter writer = new FileWriter(out)) {
om.writer().writeValue(writer, export);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

@Test
public void writeJson() {
FormatterSettings export = new FormatterSettings();

DefaultPrettyPrinter prettyPrinter =
new DefaultPrettyPrinter()
.withObjectIndenter(new DefaultIndenter().withLinefeed("\n"));
ObjectMapper om =
new ObjectMapper()
.setDefaultPrettyPrinter(prettyPrinter)
.enable(SerializationFeature.INDENT_OUTPUT);

File out = new File("example-settings.json");
try (FileWriter writer = new FileWriter(out)) {
om.writer().writeValue(writer, export);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -807,4 +807,5 @@ default JCast castTo (@NonNull final AbstractJType aType)
{
return JExpr.cast (aType, this);
}

}
18 changes: 18 additions & 0 deletions jcodemodel/src/main/java/com/helger/jcodemodel/IJGenerable.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,28 @@

import org.jspecify.annotations.NonNull;

import com.helger.jcodemodel.JOp.Precedence;

/**
* Common interface for code components that can generate uses of themselves.
*/
public interface IJGenerable extends IJObject
{
void generate (@NonNull IJFormatter f);

/// Indicates the operator precedence at which an operator addition can change the meaning of
/// this. Used to check the need for parentheses.
///
/// For example, an "a+b*c" element would return the precedence of "+", and any operator with
/// an higher precedence could break it : a "++" operator would require parentheses since
/// "a+b*c++" is not the same as "(a+b*c)++"
///
/// Most elements are not operator-sensitive so the default is the max precedence (token). For
/// example method call( "myFunction()" )
///
/// @return the lowest operator precedence.
default JOp.Precedence operatorPrecedence ()
{
return Precedence.TOKEN;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@

import com.helger.base.enforce.ValueEnforcer;
import com.helger.base.equals.EqualsHelper;
import com.helger.jcodemodel.JOp.Precedence;

/**
* array component reference.
Expand Down Expand Up @@ -92,7 +93,30 @@ public IJExpression index ()

public void generate (@NonNull final IJFormatter f)
{
f.generable (m_aArray).print ('[').generable (m_aIndex).print (']');
boolean parentheses = true;
switch (f.settings ().parentheses.global)
{
case ALWAYS ->
{
parentheses = true;
}
case NOTOKEN ->
{
parentheses = m_aArray.operatorPrecedence () != Precedence.TOKEN;
}
case REQUIRED ->
{
parentheses = Precedence.DEREF.higherThan (m_aArray.operatorPrecedence ());
}
default -> throw new IllegalArgumentException ("Unexpected value: " + f.settings ().parentheses.global);
}

if (parentheses)
f.print ('(');
f.generable (m_aArray);
if (parentheses)
f.print (')');
f.print ('[').generable (m_aIndex).print (']');
}

@Override
Expand All @@ -111,4 +135,10 @@ public int hashCode ()
{
return getHashCode (this, m_aArray, m_aIndex);
}

@Override
public Precedence operatorPrecedence ()
{
return Precedence.DEREF;
}
}
33 changes: 32 additions & 1 deletion jcodemodel/src/main/java/com/helger/jcodemodel/JAssignment.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.jspecify.annotations.NonNull;

import com.helger.base.equals.EqualsHelper;
import com.helger.jcodemodel.JOp.Precedence;

/**
* Assignment statements, which are also expressions.
Expand Down Expand Up @@ -119,7 +120,31 @@ public String opFull ()

public void generate (@NonNull final IJFormatter f)
{
f.generable (m_aLhs).print (opFull ()).generable (m_aRhs);
// only right side may need parentheses
boolean parentheses = true;
switch (f.settings ().parentheses.global)
{
case ALWAYS ->
{
parentheses = true;
}
case NOTOKEN ->
{
parentheses = m_aRhs.operatorPrecedence () != Precedence.TOKEN;
}
case REQUIRED ->
{
// basically only lambdas need to be parenthesized
parentheses = Precedence.ASSIGNMENT.higherThan (m_aRhs.operatorPrecedence ());
}
default -> throw new IllegalArgumentException ("Unexpected value: " + f.settings ().parentheses.global);
}
f.generable (m_aLhs).print (opFull ());
if (parentheses)
f.print ('(');
f.generable (m_aRhs);
if (parentheses)
f.print (')');
}

public void state (@NonNull final IJFormatter f)
Expand All @@ -145,4 +170,10 @@ public int hashCode ()
{
return getHashCode (this, m_aLhs, m_aRhs, m_sOperator);
}

@Override
public Precedence operatorPrecedence ()
{
return Precedence.ASSIGNMENT;
}
}
Loading
Loading