[java] Avoid using Thread.fillInStackTrace() for token context
This requires to use the option TOKEN_MANAGER_USES_PARSER
This commit is contained in:
@ -43,7 +43,7 @@
|
|||||||
<property name="ast-api-package" value="net.sourceforge.pmd.lang.ast" />
|
<property name="ast-api-package" value="net.sourceforge.pmd.lang.ast" />
|
||||||
<property name="ast-impl-package" value="${ast-api-package}.impl.javacc" />
|
<property name="ast-impl-package" value="${ast-api-package}.impl.javacc" />
|
||||||
|
|
||||||
<property name="grammar-file" value="etc/grammar/${lang-name}.jjt" />
|
<property name="grammar-file" value="${basedir}/etc/grammar/${lang-name}.jjt" />
|
||||||
|
|
||||||
<property name="parser-name" value="${lang-name}ParserImpl" />
|
<property name="parser-name" value="${lang-name}ParserImpl" />
|
||||||
<property name="parser-file" value="${target-package-dir}/${parser-name}.java" />
|
<property name="parser-file" value="${target-package-dir}/${parser-name}.java" />
|
||||||
@ -108,6 +108,10 @@
|
|||||||
<touch file="${stamp-file}" />
|
<touch file="${stamp-file}" />
|
||||||
<delete dir="${target-package-dir}" />
|
<delete dir="${target-package-dir}" />
|
||||||
<mkdir dir="${target-package-dir}" />
|
<mkdir dir="${target-package-dir}" />
|
||||||
|
|
||||||
|
<condition property="option-token-manager-uses-parser">
|
||||||
|
<resourcecontains resource="${grammar-file}" substring="TOKEN_MANAGER_USES_PARSER"/>
|
||||||
|
</condition>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="cleanup" unless="javaccBuildNotRequired">
|
<target name="cleanup" unless="javaccBuildNotRequired">
|
||||||
@ -128,7 +132,7 @@
|
|||||||
<arg value="-OUTPUT_DIRECTORY:${target-package-dir}" />
|
<arg value="-OUTPUT_DIRECTORY:${target-package-dir}" />
|
||||||
<arg value="-NODE_USES_PARSER:false" />
|
<arg value="-NODE_USES_PARSER:false" />
|
||||||
<arg value="-NODE_PACKAGE:${lang-ast-package}" />
|
<arg value="-NODE_PACKAGE:${lang-ast-package}" />
|
||||||
<arg value="etc/grammar/${lang-name}.jjt" />
|
<arg value="${grammar-file}" />
|
||||||
</java>
|
</java>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
@ -189,6 +193,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<antcall target="constants-files" />
|
<antcall target="constants-files" />
|
||||||
|
<antcall target="constants-files-token-manager-uses-parser" />
|
||||||
|
|
||||||
<!-- For compatibility -->
|
<!-- For compatibility -->
|
||||||
|
|
||||||
@ -359,8 +364,7 @@
|
|||||||
|
|
||||||
<replaceregexp>
|
<replaceregexp>
|
||||||
<regexp pattern="package ${lang-ast-package};" />
|
<regexp pattern="package ${lang-ast-package};" />
|
||||||
<substitution expression="\0
|
<substitution expression="\0${line.separator}${line.separator}import static ${lang-ast-package}.${token-constants-name}.*;" />
|
||||||
import static ${lang-ast-package}.${token-constants-name}.*;" />
|
|
||||||
<fileset file="${tokenmgr-file}" />
|
<fileset file="${tokenmgr-file}" />
|
||||||
<fileset file="${parser-file}" />
|
<fileset file="${parser-file}" />
|
||||||
</replaceregexp>
|
</replaceregexp>
|
||||||
@ -455,6 +459,15 @@ public final class ${token-constants-name} \{${line.separator}
|
|||||||
|
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
<target name="constants-files-token-manager-uses-parser" if="option-token-manager-uses-parser">
|
||||||
|
<echo level="info">Option TOKEN_MANAGER_USES_PARSER is enabled</echo>
|
||||||
|
<replaceregexp flags="g">
|
||||||
|
<regexp pattern="return new ${tokenmgr-name}\(cs\);" />
|
||||||
|
<substitution expression="return new ${parser-name}(cs).token_source;" />
|
||||||
|
<fileset file="${token-constants-file}"/>
|
||||||
|
</replaceregexp>
|
||||||
|
</target>
|
||||||
|
|
||||||
<target name="cleanup-nodes">
|
<target name="cleanup-nodes">
|
||||||
|
|
||||||
<replaceregexp flags="g">
|
<replaceregexp flags="g">
|
||||||
|
@ -279,6 +279,7 @@ options {
|
|||||||
MULTI = true;
|
MULTI = true;
|
||||||
VISITOR = true;
|
VISITOR = true;
|
||||||
NODE_PACKAGE="net.sourceforge.pmd.lang.java.ast";
|
NODE_PACKAGE="net.sourceforge.pmd.lang.java.ast";
|
||||||
|
TOKEN_MANAGER_USES_PARSER = true;
|
||||||
|
|
||||||
// disable the calculation of expected tokens when a parse error occurs
|
// disable the calculation of expected tokens when a parse error occurs
|
||||||
// depending on the possible allowed next tokens, this
|
// depending on the possible allowed next tokens, this
|
||||||
@ -292,9 +293,10 @@ options {
|
|||||||
|
|
||||||
PARSER_BEGIN(JavaParserImpl)
|
PARSER_BEGIN(JavaParserImpl)
|
||||||
package net.sourceforge.pmd.lang.java.ast;
|
package net.sourceforge.pmd.lang.java.ast;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Collections;
|
import java.util.Deque;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -305,6 +307,7 @@ import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken;
|
|||||||
import net.sourceforge.pmd.lang.ast.Node;
|
import net.sourceforge.pmd.lang.ast.Node;
|
||||||
import net.sourceforge.pmd.lang.ast.TokenMgrError;
|
import net.sourceforge.pmd.lang.ast.TokenMgrError;
|
||||||
import net.sourceforge.pmd.lang.ast.Node;
|
import net.sourceforge.pmd.lang.ast.Node;
|
||||||
|
import net.sourceforge.pmd.lang.java.ast.JavaParserImplTokenManager.TokenContext;
|
||||||
import net.sourceforge.pmd.lang.java.types.JPrimitiveType.PrimitiveTypeKind;
|
import net.sourceforge.pmd.lang.java.types.JPrimitiveType.PrimitiveTypeKind;
|
||||||
|
|
||||||
class JavaParserImpl {
|
class JavaParserImpl {
|
||||||
@ -582,6 +585,13 @@ class JavaParserImpl {
|
|||||||
*/
|
*/
|
||||||
private boolean inExplicitConstructorInvoc = false;
|
private boolean inExplicitConstructorInvoc = false;
|
||||||
|
|
||||||
|
private Deque<TokenContext> tokenContexts = new ArrayDeque<TokenContext>();
|
||||||
|
TokenContext determineTokenContext() {
|
||||||
|
if (tokenContexts.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return tokenContexts.peek();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PARSER_END(JavaParserImpl)
|
PARSER_END(JavaParserImpl)
|
||||||
|
|
||||||
@ -597,22 +607,7 @@ TOKEN_MGR_DECLS :
|
|||||||
java.util.regex.Pattern.compile("^}(?:[^\"\\\\\n\r]|\\\\(?:[ntbrfs\\\\'\"]|[0-7][0-7]?|[0-3][0-7][0-7]))*(\\{|\")");
|
java.util.regex.Pattern.compile("^}(?:[^\"\\\\\n\r]|\\\\(?:[ntbrfs\\\\'\"]|[0-7][0-7]?|[0-3][0-7][0-7]))*(\\{|\")");
|
||||||
|
|
||||||
private TokenContext determineContext() {
|
private TokenContext determineContext() {
|
||||||
Throwable t = new Throwable().fillInStackTrace();
|
return parser.determineTokenContext();
|
||||||
for (StackTraceElement e : t.getStackTrace()) {
|
|
||||||
String method = e.getMethodName();
|
|
||||||
if ("TextBlockTemplate".equals(method)) {
|
|
||||||
return TokenContext.TEXT_BLOCK_TEMPLATE;
|
|
||||||
} else if ("StringTemplate".equals(method)) {
|
|
||||||
return TokenContext.STRING_TEMPLATE;
|
|
||||||
} else if ("Block".equals(method)
|
|
||||||
|| "ClassOrInterfaceBody".equals(method)
|
|
||||||
|| "ArrayInitializer".equals(method)
|
|
||||||
|| "MemberValueArrayInitializer".equals(method)
|
|
||||||
|| "SwitchBlock".equals(method)) {
|
|
||||||
return TokenContext.BLOCK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken rereadTokenAs(int kind, int length) {
|
private net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken rereadTokenAs(int kind, int length) {
|
||||||
@ -1286,11 +1281,11 @@ void EnumDeclaration():
|
|||||||
void EnumBody():
|
void EnumBody():
|
||||||
{}
|
{}
|
||||||
{
|
{
|
||||||
"{"
|
"{" { tokenContexts.push(TokenContext.BLOCK); }
|
||||||
[ EnumConstant() ( LOOKAHEAD(2) "," EnumConstant() )* ]
|
[ EnumConstant() ( LOOKAHEAD(2) "," EnumConstant() )* ]
|
||||||
[ "," { jjtThis.setTrailingComma(); } ]
|
[ "," { jjtThis.setTrailingComma(); } ]
|
||||||
[ ";" { jjtThis.setSeparatorSemi(); } ( ClassOrInterfaceBodyDeclaration() )* ]
|
[ ";" { jjtThis.setSeparatorSemi(); } ( ClassOrInterfaceBodyDeclaration() )* ]
|
||||||
"}"
|
"}" { tokenContexts.pop(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnumConstant():
|
void EnumConstant():
|
||||||
@ -1333,9 +1328,9 @@ void RecordComponent():
|
|||||||
void RecordBody():
|
void RecordBody():
|
||||||
{}
|
{}
|
||||||
{
|
{
|
||||||
"{"
|
"{" { tokenContexts.push(TokenContext.BLOCK); }
|
||||||
( RecordBodyDeclaration() )*
|
( RecordBodyDeclaration() )*
|
||||||
"}"
|
"}" { tokenContexts.pop(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecordBodyDeclaration() #void :
|
void RecordBodyDeclaration() #void :
|
||||||
@ -1375,7 +1370,9 @@ void TypeParameter():
|
|||||||
void ClassOrInterfaceBody():
|
void ClassOrInterfaceBody():
|
||||||
{}
|
{}
|
||||||
{
|
{
|
||||||
"{" ( ClassOrInterfaceBodyDeclaration() )* "}"
|
"{" { tokenContexts.push(TokenContext.BLOCK); }
|
||||||
|
( ClassOrInterfaceBodyDeclaration() )*
|
||||||
|
"}" { tokenContexts.pop(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassOrInterfaceBodyDeclaration() #void:
|
void ClassOrInterfaceBodyDeclaration() #void:
|
||||||
@ -1436,7 +1433,9 @@ void VariableInitializer() #void:
|
|||||||
void ArrayInitializer() :
|
void ArrayInitializer() :
|
||||||
{}
|
{}
|
||||||
{
|
{
|
||||||
"{" [ VariableInitializer() ( LOOKAHEAD(2) "," VariableInitializer() )* ] [ "," ] "}"
|
"{" { tokenContexts.push(TokenContext.BLOCK); }
|
||||||
|
[ VariableInitializer() ( LOOKAHEAD(2) "," VariableInitializer() )* ] [ "," ]
|
||||||
|
"}" { tokenContexts.pop(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void MethodDeclaration() :
|
void MethodDeclaration() :
|
||||||
@ -1501,10 +1500,10 @@ void ConstructorDeclaration() :
|
|||||||
private void ConstructorBlock() #Block:
|
private void ConstructorBlock() #Block:
|
||||||
{}
|
{}
|
||||||
{
|
{
|
||||||
"{"
|
"{" { tokenContexts.push(TokenContext.BLOCK); }
|
||||||
[ LOOKAHEAD(ExplicitConstructorInvocation()) ExplicitConstructorInvocation() ]
|
[ LOOKAHEAD(ExplicitConstructorInvocation()) ExplicitConstructorInvocation() ]
|
||||||
( BlockStatement() )*
|
( BlockStatement() )*
|
||||||
"}"
|
"}" { tokenContexts.pop(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExplicitConstructorInvocation() :
|
void ExplicitConstructorInvocation() :
|
||||||
@ -2329,19 +2328,27 @@ void Template() :
|
|||||||
void StringTemplate() #void :
|
void StringTemplate() #void :
|
||||||
{}
|
{}
|
||||||
{
|
{
|
||||||
|
{ tokenContexts.push(TokenContext.STRING_TEMPLATE); }
|
||||||
|
|
||||||
<STRING_TEMPLATE_BEGIN> { setLastTokenImage(jjtThis); } #TemplateFragment
|
<STRING_TEMPLATE_BEGIN> { setLastTokenImage(jjtThis); } #TemplateFragment
|
||||||
EmbeddedExpression()
|
EmbeddedExpression()
|
||||||
( <STRING_TEMPLATE_MID> { setLastTokenImage(jjtThis); } #TemplateFragment EmbeddedExpression() )*
|
( <STRING_TEMPLATE_MID> { setLastTokenImage(jjtThis); } #TemplateFragment EmbeddedExpression() )*
|
||||||
<STRING_TEMPLATE_END> { setLastTokenImage(jjtThis); } #TemplateFragment
|
<STRING_TEMPLATE_END> { setLastTokenImage(jjtThis); } #TemplateFragment
|
||||||
|
|
||||||
|
{ tokenContexts.pop(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBlockTemplate() #void :
|
void TextBlockTemplate() #void :
|
||||||
{}
|
{}
|
||||||
{
|
{
|
||||||
|
{ tokenContexts.push(TokenContext.TEXT_BLOCK_TEMPLATE); }
|
||||||
|
|
||||||
<TEXT_BLOCK_TEMPLATE_BEGIN> { setLastTokenImage(jjtThis); } #TemplateFragment
|
<TEXT_BLOCK_TEMPLATE_BEGIN> { setLastTokenImage(jjtThis); } #TemplateFragment
|
||||||
EmbeddedExpression()
|
EmbeddedExpression()
|
||||||
( <TEXT_BLOCK_TEMPLATE_MID> { setLastTokenImage(jjtThis); } #TemplateFragment EmbeddedExpression() )*
|
( <TEXT_BLOCK_TEMPLATE_MID> { setLastTokenImage(jjtThis); } #TemplateFragment EmbeddedExpression() )*
|
||||||
<TEXT_BLOCK_TEMPLATE_END> { setLastTokenImage(jjtThis); } #TemplateFragment
|
<TEXT_BLOCK_TEMPLATE_END> { setLastTokenImage(jjtThis); } #TemplateFragment
|
||||||
|
|
||||||
|
{ tokenContexts.pop(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmbeddedExpression() #void :
|
void EmbeddedExpression() #void :
|
||||||
@ -2507,7 +2514,9 @@ void LabeledStatement() :
|
|||||||
void Block() :
|
void Block() :
|
||||||
{}
|
{}
|
||||||
{
|
{
|
||||||
"{" ( BlockStatement() )* "}"
|
"{" { tokenContexts.push(TokenContext.BLOCK); }
|
||||||
|
( BlockStatement() )*
|
||||||
|
"}" { tokenContexts.pop(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockStatement() #void:
|
void BlockStatement() #void:
|
||||||
@ -2638,12 +2647,12 @@ void SwitchStatement():
|
|||||||
void SwitchBlock() #void:
|
void SwitchBlock() #void:
|
||||||
{}
|
{}
|
||||||
{
|
{
|
||||||
"{"
|
"{" { tokenContexts.push(TokenContext.BLOCK); }
|
||||||
(
|
(
|
||||||
LOOKAHEAD(SwitchLabel() ":") (SwitchFallthroughBranch())+
|
LOOKAHEAD(SwitchLabel() ":") (SwitchFallthroughBranch())+
|
||||||
| (SwitchArrowBranch())*
|
| (SwitchArrowBranch())*
|
||||||
)
|
)
|
||||||
"}"
|
"}" { tokenContexts.pop(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitchArrowBranch():
|
void SwitchArrowBranch():
|
||||||
@ -2940,7 +2949,9 @@ void MemberValue() #void:
|
|||||||
void MemberValueArrayInitializer():
|
void MemberValueArrayInitializer():
|
||||||
{}
|
{}
|
||||||
{
|
{
|
||||||
"{" (MemberValue() ( LOOKAHEAD(2) "," MemberValue() )*)? [ "," ] "}"
|
"{" { tokenContexts.push(TokenContext.BLOCK); }
|
||||||
|
(MemberValue() ( LOOKAHEAD(2) "," MemberValue() )*)? [ "," ]
|
||||||
|
"}" { tokenContexts.pop(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2965,7 +2976,9 @@ void AnnotationTypeDeclaration():
|
|||||||
void AnnotationTypeBody():
|
void AnnotationTypeBody():
|
||||||
{}
|
{}
|
||||||
{
|
{
|
||||||
"{" ( AnnotationTypeMemberDeclaration() )* "}"
|
"{" { tokenContexts.push(TokenContext.BLOCK); }
|
||||||
|
( AnnotationTypeMemberDeclaration() )*
|
||||||
|
"}" { tokenContexts.pop(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnnotationTypeMemberDeclaration() #void:
|
void AnnotationTypeMemberDeclaration() #void:
|
||||||
@ -3010,7 +3023,9 @@ void ModuleDeclaration():
|
|||||||
[LOOKAHEAD({isKeyword("open")}) <IDENTIFIER> {jjtThis.setOpen(true);}]
|
[LOOKAHEAD({isKeyword("open")}) <IDENTIFIER> {jjtThis.setOpen(true);}]
|
||||||
LOOKAHEAD({isKeyword("module")}) <IDENTIFIER>
|
LOOKAHEAD({isKeyword("module")}) <IDENTIFIER>
|
||||||
ModuleName()
|
ModuleName()
|
||||||
"{" (ModuleDirective())* "}"
|
"{" { tokenContexts.push(TokenContext.BLOCK); }
|
||||||
|
(ModuleDirective())*
|
||||||
|
"}" { tokenContexts.pop(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModuleDirective() #void:
|
void ModuleDirective() #void:
|
||||||
|
@ -29,7 +29,7 @@ public final class SyntacticJavaTokenizerFactory {
|
|||||||
|
|
||||||
public static TokenManager<JavaccToken> createTokenizer(CharStream cs) {
|
public static TokenManager<JavaccToken> createTokenizer(CharStream cs) {
|
||||||
final List<JavaccToken> tokenList = new ArrayList<>();
|
final List<JavaccToken> tokenList = new ArrayList<>();
|
||||||
JavaParserImplTokenManager tokenManager = new JavaParserImplTokenManager(cs) {
|
JavaParserImplTokenManager tokenManager = new JavaParserImplTokenManager(null, cs) {
|
||||||
@Override
|
@Override
|
||||||
public JavaccToken getNextToken() {
|
public JavaccToken getNextToken() {
|
||||||
JavaccToken token = super.getNextToken();
|
JavaccToken token = super.getNextToken();
|
||||||
@ -40,6 +40,7 @@ public final class SyntacticJavaTokenizerFactory {
|
|||||||
|
|
||||||
LanguageVersion latestVersion = JavaLanguageModule.getInstance().getLatestVersion();
|
LanguageVersion latestVersion = JavaLanguageModule.getInstance().getLatestVersion();
|
||||||
JavaParserImpl parser = new JavaParserImpl(tokenManager);
|
JavaParserImpl parser = new JavaParserImpl(tokenManager);
|
||||||
|
tokenManager.parser = parser;
|
||||||
parser.setJdkVersion(JavaLanguageProperties.getInternalJdkVersion(latestVersion));
|
parser.setJdkVersion(JavaLanguageProperties.getInternalJdkVersion(latestVersion));
|
||||||
parser.setPreview(JavaLanguageProperties.isPreviewEnabled(latestVersion));
|
parser.setPreview(JavaLanguageProperties.isPreviewEnabled(latestVersion));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user