#1056 Making sure indentation level in formatting writer never goes below 0

This commit is contained in:
Gunnar Morling 2017-02-04 21:39:36 +01:00 committed by Andreas Gudian
parent 40fc5612cb
commit 5564c53f41
7 changed files with 200 additions and 10 deletions

View File

@ -117,11 +117,11 @@ class IndentationCorrectingWriter extends Writer {
switch ( c ) {
case '{':
case '(':
context.indentationLevel++;
context.incrementIndentationLevel();
return IN_TEXT;
case '}':
case ')':
context.indentationLevel--;
context.decrementIndentationLevel();
return IN_TEXT;
case '\"':
return IN_STRING;
@ -139,10 +139,11 @@ class IndentationCorrectingWriter extends Writer {
*/
@Override
void doOnEntry(StateContext context) throws IOException {
context.writer.write( getIndentation( context.indentationLevel ) );
context.writer.write( getIndentation( context.getIndentationLevel() ) );
if ( DEBUG ) {
System.out.print( new String( getIndentation( context.indentationLevel ) ).replace( " ", "_" ) );
System.out.print( new String( getIndentation( context.getIndentationLevel() ) )
.replace( " ", "_" ) );
}
}
@ -173,11 +174,11 @@ class IndentationCorrectingWriter extends Writer {
switch ( c ) {
case '{':
case '(':
context.indentationLevel++;
context.incrementIndentationLevel();
return IN_TEXT;
case '}':
case ')':
context.indentationLevel--;
context.decrementIndentationLevel();
return IN_TEXT;
case '\"':
return IN_STRING;
@ -298,14 +299,14 @@ class IndentationCorrectingWriter extends Writer {
switch ( c ) {
case '{':
case '(':
context.indentationLevel++;
context.incrementIndentationLevel();
return START_OF_LINE;
case '}':
if ( context.consecutiveLineBreaks > 0 ) {
context.consecutiveLineBreaks = 0; // remove previous blank lines
}
case ')':
context.indentationLevel--;
context.decrementIndentationLevel();
return START_OF_LINE;
case '\r':
return isWindows() ? IN_LINE_BREAK : AFTER_LINE_BREAK;
@ -407,7 +408,7 @@ class IndentationCorrectingWriter extends Writer {
/**
* Keeps track of the current indentation level, as implied by brace characters.
*/
int indentationLevel;
private int indentationLevel;
/**
* The number of consecutive line-breaks when within {@link State#AFTER_LINE_BREAK}.
@ -423,5 +424,22 @@ class IndentationCorrectingWriter extends Writer {
this.lastStateChange = off;
this.currentIndex = 0;
}
void incrementIndentationLevel() {
indentationLevel++;
}
void decrementIndentationLevel() {
// decrementing below 0 indicates misbalanced braces in the code, typically because too many closing braces
// are given in an expression; we let that code pass through, the compiler will complain eventually about
// the malformed source file
if ( indentationLevel > 0 ) {
indentationLevel--;
}
}
int getIndentationLevel() {
return indentationLevel;
}
}
}

View File

@ -0,0 +1,29 @@
/**
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* 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.
*/
package org.mapstruct.ap.test.erroneous.misbalancedbraces;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@Mapper
public interface MapperWithMalformedExpression {
@Mapping(target = "foo", expression = "java( Boolean.valueOf( source.foo > 0 ) ) )")
Target sourceToTarget(Source source);
}

View File

@ -0,0 +1,54 @@
/**
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* 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.
*/
package org.mapstruct.ap.test.erroneous.misbalancedbraces;
import javax.tools.Diagnostic.Kind;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.WithClasses;
import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult;
import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic;
import org.mapstruct.ap.testutil.compilation.annotation.DisableCheckstyle;
import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome;
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
/**
* Test for making sure that expressions with too many closing braces are passed through, letting the compiler raise an
* error.
*
* @author Gunnar Morling
*/
@WithClasses({ MapperWithMalformedExpression.class, Source.class, Target.class })
@DisableCheckstyle
@RunWith(AnnotationProcessorTestRunner.class)
public class MisbalancedBracesTest {
// the compiler messages due to the additional closing brace differ between JDK and Eclipse, hence we can only
// assert on the line number but not the message
@Test
@IssueKey("1056")
@ExpectedCompilationOutcome(
value = CompilationResult.FAILED,
diagnostics = { @Diagnostic(kind = Kind.ERROR, line = 20) }
)
public void expressionWithMisbalancedBracesIsPassedThrough() {
}
}

View File

@ -0,0 +1,25 @@
/**
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* 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.
*/
package org.mapstruct.ap.test.erroneous.misbalancedbraces;
public class Source {
//CHECKSTYLE:OFF
public int foo;
}

View File

@ -0,0 +1,25 @@
/**
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* 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.
*/
package org.mapstruct.ap.test.erroneous.misbalancedbraces;
public class Target {
//CHECKSTYLE:OFF
public boolean foo;
}

View File

@ -0,0 +1,34 @@
/**
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* 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.
*/
package org.mapstruct.ap.testutil.compilation.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Disables CheckStyle for the sources generated by this test.
*
* @author Gunnar Morling
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DisableCheckstyle {
}

View File

@ -43,6 +43,7 @@ import org.mapstruct.ap.testutil.WithClasses;
import org.mapstruct.ap.testutil.WithServiceImplementation;
import org.mapstruct.ap.testutil.WithServiceImplementations;
import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult;
import org.mapstruct.ap.testutil.compilation.annotation.DisableCheckstyle;
import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome;
import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption;
import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOptions;
@ -78,6 +79,7 @@ abstract class CompilingStatement extends Statement {
private final FrameworkMethod method;
private final CompilationCache compilationCache;
private final boolean runCheckstyle;
private Statement next;
private String classOutputDir;
@ -88,6 +90,7 @@ abstract class CompilingStatement extends Statement {
CompilingStatement(FrameworkMethod method, CompilationCache compilationCache) {
this.method = method;
this.compilationCache = compilationCache;
this.runCheckstyle = !method.getMethod().getDeclaringClass().isAnnotationPresent( DisableCheckstyle.class );
this.compilationRequest = new CompilationRequest( getTestClasses(), getServices(), getProcessorOptions() );
}
@ -202,7 +205,9 @@ abstract class CompilingStatement extends Statement {
assertDiagnostics( actualResult.getDiagnostics(), expectedResult.getDiagnostics() );
assertCheckstyleRules();
if ( runCheckstyle ) {
assertCheckstyleRules();
}
}
private void assertCheckstyleRules() throws Exception {