From 0f9b290398aac86ef56fe3c4e9c3ff88fdd53466 Mon Sep 17 00:00:00 2001 From: A Pottinger Date: Sat, 29 Jan 2022 15:08:14 -0800 Subject: [PATCH] Closes #290: Support detection of mixed modes in preproc. Make a more friendly error message when the user is mixing modes, allowing for localization of error. --- build/shared/lib/languages/PDE.properties | 3 ++- build/shared/lib/languages/PDE_es.properties | 1 + .../java/preproc/PdeParseTreeListener.java | 19 ++++++++++++++++++- .../mode/java/preproc/Processing.g4 | 11 +++++++++-- .../processing/mode/java/ParserTests.java | 5 +++++ 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/build/shared/lib/languages/PDE.properties b/build/shared/lib/languages/PDE.properties index 6203e7527c..3c88bfd917 100644 --- a/build/shared/lib/languages/PDE.properties +++ b/build/shared/lib/languages/PDE.properties @@ -415,6 +415,7 @@ editor.status.bad.generic = Possibly missing type in generic near '%s'? editor.status.bad.identifier = Bad identifier? Did you forget a variable or start an identifier with digits near '%s'? editor.status.bad.parameter = Error on parameter or method declaration near '%s'? editor.status.bad.import = Import not allowed here. +editor.status.bad.mixed_mode = You may be mixing active and static modes which is not allowed. editor.status.extraneous = Incomplete statement or extra code near '%s'? editor.status.mismatched = Missing operator, semicolon, or '}' near '%s'? editor.status.missing.name = Missing name or ; near '%s'? @@ -644,4 +645,4 @@ movie_maker.progress.creating_output_file = Creating output file movie_maker.progress.initializing = Initializing... movie_maker.progress.processing = Processing %s. -movie_maker.progress.handling_frame = Converting frame %s of %s... \ No newline at end of file +movie_maker.progress.handling_frame = Converting frame %s of %s... diff --git a/build/shared/lib/languages/PDE_es.properties b/build/shared/lib/languages/PDE_es.properties index 2fa095889c..e732a5159a 100644 --- a/build/shared/lib/languages/PDE_es.properties +++ b/build/shared/lib/languages/PDE_es.properties @@ -387,6 +387,7 @@ editor.status.bad.identifier = Error en este identificador? Es posible que tu ol editor.status.bad.generic = Error en genérico cerca '%s'. Falta un tipo? editor.status.bad.parameter = Error en un parámetro o una declaración de método cerca '%s'? editor.status.bad.import = Una declaración de importación no es permitida en una definición de una clasa. +editor.status.bad.mixed_mode = Es possible que estás usando el modo estático y activo. editor.status.extraneous = Una declaración incompleta o un imprevisto clave cerca '%s'? editor.status.mismatched = Falta un punto y coma, un operador, o un '}' cerca '%s'? editor.status.missing.name = Falta ; o nombre cerca '%s'? diff --git a/java/src/processing/mode/java/preproc/PdeParseTreeListener.java b/java/src/processing/mode/java/preproc/PdeParseTreeListener.java index b422d08f42..ac15eaef11 100644 --- a/java/src/processing/mode/java/preproc/PdeParseTreeListener.java +++ b/java/src/processing/mode/java/preproc/PdeParseTreeListener.java @@ -316,6 +316,23 @@ public void exitProcessingSketch(ProcessingParser.ProcessingSketchContext ctx) { footerResult = prepareFooter(rewriter, length); } + @Override + public void enterWarnMixedModes(ProcessingParser.WarnMixedModesContext ctx) { + pdeParseTreeErrorListenerMaybe.ifPresent((listener) -> { + Token token = ctx.getStart(); + int line = token.getLine(); + int charOffset = token.getCharPositionInLine(); + + listener.onError(new PdePreprocessIssue( + line, + charOffset, + PreprocessIssueMessageSimplifier.getLocalStr( + "editor.status.bad.mixed_mode" + ) + )); + }); + } + /** * Endpoint for ANTLR to call when finished parsing a method invocatino. * @@ -770,7 +787,7 @@ protected boolean calledFromGlobalOrSetup(ParserRuleContext callContext) { * @return True if setup and false otherwise. */ protected boolean isMethodSetup(ParserRuleContext declaration) { - if (declaration.getChildCount() < 2) { + if (declaration == null || declaration.getChildCount() < 2) { return false; } return declaration.getChild(1).getText().equals("setup"); diff --git a/java/src/processing/mode/java/preproc/Processing.g4 b/java/src/processing/mode/java/preproc/Processing.g4 index 2f9b1c6ff3..2c370eff0b 100644 --- a/java/src/processing/mode/java/preproc/Processing.g4 +++ b/java/src/processing/mode/java/preproc/Processing.g4 @@ -23,6 +23,7 @@ processingSketch : javaProcessingSketch | staticProcessingSketch | activeProcessingSketch + | warnMixedModes ; // java mode, is a compilation unit @@ -30,20 +31,26 @@ javaProcessingSketch : packageDeclaration? importDeclaration* typeDeclaration+ EOF ; +// No method declarations, just statements staticProcessingSketch : (importDeclaration | blockStatement)* EOF ; // active mode, has function definitions activeProcessingSketch - : (importDeclaration | classBodyDeclaration)* EOF - ; + : (importDeclaration | classBodyDeclaration)* EOF + ; variableDeclaratorId : warnTypeAsVariableName | IDENTIFIER ('[' ']')* ; +warnMixedModes + : (importDeclaration | classBodyDeclaration | blockStatement)* blockStatement classBodyDeclaration (importDeclaration | classBodyDeclaration | blockStatement)* + | (importDeclaration | classBodyDeclaration | blockStatement)* classBodyDeclaration blockStatement (importDeclaration | classBodyDeclaration | blockStatement)* + ; + // bug #93 // https://github.com/processing/processing/issues/93 // prevent from types being used as variable names diff --git a/java/test/processing/mode/java/ParserTests.java b/java/test/processing/mode/java/ParserTests.java index 7478bf9db5..e0df2f6367 100644 --- a/java/test/processing/mode/java/ParserTests.java +++ b/java/test/processing/mode/java/ParserTests.java @@ -405,4 +405,9 @@ public void testSizeThis() { expectGood("sizethis"); } + @Test + public void testMixing() { + expectRunnerException("mixing", 1); + } + }