mirror of
https://github.com/processing/processing4.git
synced 2026-02-03 05:39:18 +01:00
Refactor ANTLR message simplification infrastructure.
Refactor ANTLR message simplification infrastructure to reduce class count within preproc given @benfy feedback within https://github.com/processing/processing4/pull/1. Note that some supporting are left out but those can be further refactored behind classes as desired but strategies are all made anon or inner.
This commit is contained in:
@@ -32,7 +32,7 @@ import processing.mode.java.pdex.TextTransform;
|
||||
import processing.mode.java.preproc.PdePreprocessor.Mode;
|
||||
import processing.mode.java.preproc.code.*;
|
||||
import processing.mode.java.preproc.issue.PdePreprocessIssue;
|
||||
import processing.mode.java.preproc.issue.strategy.MessageSimplifierUtil;
|
||||
import processing.mode.java.preproc.issue.PreprocessIssueMessageSimplifier;
|
||||
|
||||
/**
|
||||
* ANTLR tree traversal listener that preforms code rewrites as part of sketch preprocessing.
|
||||
@@ -387,7 +387,7 @@ public class PdeParseTreeListener extends ProcessingBaseListener {
|
||||
listener.onError(new PdePreprocessIssue(
|
||||
line,
|
||||
charOffset,
|
||||
MessageSimplifierUtil.getLocalStr("editor.status.bad.import")
|
||||
PreprocessIssueMessageSimplifier.getLocalStr("editor.status.bad.import")
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
package processing.mode.java.preproc.issue;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -43,7 +43,7 @@ public class IssueLocationFactory {
|
||||
/**
|
||||
* Determine where an issue should be reported.
|
||||
*
|
||||
* @param simplification The issue simplification generated from {PreprocessIssueMessageSimplifierFacade}.
|
||||
* @param simplification The issue simplification generated from {PreprocessIssueMessageSimplifier}.
|
||||
* @param originalLine The original line (1 indexed) on which the issue was reported.
|
||||
* @param originalOffset The original number of characters from the start of the line where the
|
||||
* the issue was reported.
|
||||
|
||||
@@ -22,15 +22,11 @@
|
||||
package processing.mode.java.preproc.issue;
|
||||
|
||||
import org.antlr.v4.runtime.BaseErrorListener;
|
||||
import org.antlr.v4.runtime.Parser;
|
||||
import org.antlr.v4.runtime.RecognitionException;
|
||||
import org.antlr.v4.runtime.Recognizer;
|
||||
import org.antlr.v4.runtime.atn.ATNConfigSet;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
|
||||
import processing.mode.java.preproc.SourceEmitter;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
@@ -40,7 +36,7 @@ import java.util.Optional;
|
||||
* <p>
|
||||
* A {BaseErrorListener} which looks for syntax errors reported by ANTLR and converts them to
|
||||
* {PdePreprocessIssue}s that are consumable by a {PdePreprocessIssueListener}. It does this by
|
||||
* running the {PreprocessIssueMessageSimplifierFacade} to generate a more user-friendly error message
|
||||
* running the {PreprocessIssueMessageSimplifier} to generate a more user-friendly error message
|
||||
* before informing the provided listener.
|
||||
* </p>
|
||||
*/
|
||||
@@ -81,7 +77,7 @@ public class PdeIssueEmitter extends BaseErrorListener {
|
||||
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line,
|
||||
int charPositionInLine, String msg, RecognitionException e) {
|
||||
|
||||
PreprocessIssueMessageSimplifierFacade facade = PreprocessIssueMessageSimplifierFacade.get();
|
||||
PreprocessIssueMessageSimplifier facade = PreprocessIssueMessageSimplifier.get();
|
||||
IssueMessageSimplification simplification = facade.simplify(msg);
|
||||
|
||||
IssueLocation issueLocation;
|
||||
|
||||
@@ -0,0 +1,691 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue;
|
||||
|
||||
|
||||
import processing.app.Language;
|
||||
import processing.app.Platform;
|
||||
import processing.mode.java.preproc.code.SyntaxUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
* Facade that tries to create a better error message for syntax issues in input source.
|
||||
*
|
||||
* <p>
|
||||
* Facade that interprets error messages from ANTLR in an attempt to generate an improved error
|
||||
* message when describing grammatically incorrect input. This is distinct from compiler errors
|
||||
* caused after generating an AST.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Note that this is distinct from the {CompileErrorMessageSimplifier}. This operates on issues
|
||||
* caused in parsing and services all users whereas the {CompileErrorMessageSimplifier} only
|
||||
* operates on issues generated after preprocessing has been successful.
|
||||
* </p>
|
||||
*/
|
||||
public class PreprocessIssueMessageSimplifier {
|
||||
|
||||
private static AtomicReference<PreprocessIssueMessageSimplifier> instance = new AtomicReference<>();
|
||||
|
||||
// List of strategies to use when trying to simplify an error message.
|
||||
private List<PreprocIssueMessageSimplifierStrategy> strategies;
|
||||
|
||||
|
||||
/* ========================
|
||||
* === Public interface ===
|
||||
* ========================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get a shared instance of this singleton.
|
||||
*
|
||||
* @return Shared instance of this singleton, creating that shared instance if one did not exist
|
||||
* previously.
|
||||
*/
|
||||
public static PreprocessIssueMessageSimplifier get() {
|
||||
instance.compareAndSet(null, new PreprocessIssueMessageSimplifier());
|
||||
return instance.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a localized template string.
|
||||
*
|
||||
* @param stringName Name of the template.
|
||||
* @return The template's contents prior to rendering.
|
||||
*/
|
||||
public static String getLocalStr(String stringName) {
|
||||
String errStr;
|
||||
String retStr;
|
||||
|
||||
if (Platform.isInit()) {
|
||||
errStr = Language.text("editor.status.error.syntax");
|
||||
retStr = Language.text(stringName);
|
||||
} else {
|
||||
errStr = DefaultErrorLocalStrSet.get().get("editor.status.error.syntax").orElse("Error");
|
||||
retStr = DefaultErrorLocalStrSet.get().get(stringName).orElse(stringName);
|
||||
}
|
||||
|
||||
return String.format(errStr, retStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to improve an error message.
|
||||
*
|
||||
* @param originalMessage Error message generated from ANTLR.
|
||||
* @return An improved error message or the originalMessage if no improvements could be made.
|
||||
*/
|
||||
public IssueMessageSimplification simplify(String originalMessage) {
|
||||
Optional<IssueMessageSimplification> matching = strategies.stream()
|
||||
.map((x) -> x.simplify(originalMessage))
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.findFirst();
|
||||
|
||||
return matching.orElse(new IssueMessageSimplification(originalMessage));
|
||||
}
|
||||
|
||||
/* ============================
|
||||
* === Enumerate strategies ===
|
||||
* ============================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a new syntax issue message simplifier with the default simplifier strategies.
|
||||
*/
|
||||
private PreprocessIssueMessageSimplifier() {
|
||||
strategies = new ArrayList<>();
|
||||
strategies.add(createMissingCurlyAtStartSimplifierStrategy());
|
||||
strategies.add(createMissingCurlyAtSemicolonSimplifierStrategy());
|
||||
strategies.add(createInvalidGenericDefinitionStrategy());
|
||||
strategies.add(createMissingIdentifierSimplifierStrategy());
|
||||
strategies.add(createKnownMissingSimplifierStrategy());
|
||||
strategies.add(createExtraneousInputSimplifierStrategy());
|
||||
strategies.add(createMismatchedInputSimplifierStrategy());
|
||||
strategies.add(createInvalidAssignmentStrategy());
|
||||
strategies.add(createVariableDeclarationMissingTypeStrategy());
|
||||
strategies.add(createInvalidIdentifierStrategy());
|
||||
strategies.add(createMissingClassNameStrategy());
|
||||
strategies.add(createMethodMissingNameStrategy());
|
||||
strategies.add(createErrorOnParameterStrategy());
|
||||
strategies.add(createMissingDoubleQuoteStrategy());
|
||||
strategies.add(createMissingSingleQuoteStrategy());
|
||||
strategies.add(createUnbalancedCurlyStrategy());
|
||||
strategies.add(createUnbalancedParenStrategy());
|
||||
strategies.add(createUnbalancedChevStrategy());
|
||||
strategies.add(new DefaultMessageSimplifier());
|
||||
}
|
||||
|
||||
/* ===========================
|
||||
* ==== Utility Functions ====
|
||||
* ===========================
|
||||
*
|
||||
* Misc utility functions for message simplification where some are protected to support unit
|
||||
* testing.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the snippet of "offending code" from an error message if given.
|
||||
*
|
||||
* @param area The area from which to extract the offending code.
|
||||
* @return The offending code described in the error message or the original message if the subset
|
||||
* describing the offending code could not be found.
|
||||
*/
|
||||
protected static String getOffendingArea(String area) {
|
||||
return getOffendingArea(area, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the snippet of "offending code" from an error message if given.
|
||||
*
|
||||
* @param area The area from which to extract the offending code.
|
||||
* @param removeNewline Flag indicating if newlines should be removed or not.
|
||||
* @return The offending code described in the error message or the original message if the subset
|
||||
* describing the offending code could not be found.
|
||||
*/
|
||||
private static String getOffendingArea(String area, boolean removeNewline) {
|
||||
if (!area.contains("viable alternative")) {
|
||||
return area;
|
||||
}
|
||||
|
||||
String content = area.replace("no viable alternative at input \'", "");
|
||||
|
||||
if (removeNewline) {
|
||||
String[] contentLines = content.replace("\n", "\\n").split("\\\\n");
|
||||
content = contentLines[contentLines.length - 1];
|
||||
}
|
||||
|
||||
if (content.endsWith("'")) {
|
||||
return content.substring(0, content.length() - 1);
|
||||
} else {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an generic error message.
|
||||
*
|
||||
* @param unlocalized The unlocalized string. Will be included in resulting message but with
|
||||
* surrounding localized text.
|
||||
* @return Semi-localized message.
|
||||
*/
|
||||
private static String getLocalizedGenericError(String unlocalized) {
|
||||
String template = getLocalStr("editor.status.error_on");
|
||||
return String.format(template, unlocalized);
|
||||
}
|
||||
|
||||
/* ==================================
|
||||
* ==== Interface for Strategies ====
|
||||
* ==================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface for strategies that improve preprocess error messages before showing them to the user.
|
||||
*/
|
||||
protected interface PreprocIssueMessageSimplifierStrategy {
|
||||
|
||||
/**
|
||||
* Attempt to simplify an error message.
|
||||
*
|
||||
* @param message The message to be simplified.
|
||||
* @return An optional with an improved message or an empty optional if no improvements could be
|
||||
* made by this strategy.
|
||||
*/
|
||||
Optional<IssueMessageSimplification> simplify(String message);
|
||||
|
||||
}
|
||||
|
||||
/* ==================================================================
|
||||
* ==== Strategies where the same character must appear in pairs ====
|
||||
* ==================================================================
|
||||
*
|
||||
* Strategies detecting issues reported in ANTLR where a character was expected to appear an even
|
||||
* number of times. This is like double or single quotes. Note that some are left protected to
|
||||
* support unit testing.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Strategy to check to make sure that the number of occurrences of a token are even.
|
||||
*
|
||||
* <p>
|
||||
* Strategy to ensure that there are an even number of tokens like even number of double quotes
|
||||
* for example.
|
||||
* </p>
|
||||
*/
|
||||
protected static class EvenCountTemplateMessageSimplifierStrategy
|
||||
implements PreprocIssueMessageSimplifierStrategy {
|
||||
|
||||
private final String token;
|
||||
private final Optional<String> filter;
|
||||
|
||||
/**
|
||||
* Create a new even count simplifier strategy.
|
||||
*
|
||||
* @param newToken The token that needs to be balanced.
|
||||
*/
|
||||
protected EvenCountTemplateMessageSimplifierStrategy(String newToken) {
|
||||
token = newToken;
|
||||
filter = Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new even count simplifier strategy where some text needs to be filtered out prior to
|
||||
* checking if the simplifier is relevant.
|
||||
*
|
||||
* @param newToken The token that needs to be balanced.
|
||||
* @param newFilter The text to be filtered out.
|
||||
*/
|
||||
protected EvenCountTemplateMessageSimplifierStrategy(String newToken, String newFilter) {
|
||||
token = newToken;
|
||||
filter = Optional.of(newFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<IssueMessageSimplification> simplify(String message) {
|
||||
String messageContent = getOffendingArea(message);
|
||||
|
||||
if (filter.isPresent()) {
|
||||
messageContent = messageContent.replace(filter.get(), "");
|
||||
}
|
||||
|
||||
int count = SyntaxUtil.getCount(messageContent, token);
|
||||
|
||||
if (count % 2 == 0) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
String newMessage = String.format(
|
||||
getLocalStr("editor.status.missing.default").replace("%c", "%s"),
|
||||
token
|
||||
);
|
||||
return Optional.of(
|
||||
new IssueMessageSimplification(newMessage)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy to detect uneven single quotes.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createMissingSingleQuoteStrategy() {
|
||||
return new EvenCountTemplateMessageSimplifierStrategy("\'", "\\'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy to detect uneven double quotes.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createMissingDoubleQuoteStrategy() {
|
||||
return new EvenCountTemplateMessageSimplifierStrategy("\"", "\\\"");
|
||||
}
|
||||
|
||||
/* ======================================================
|
||||
* ==== Strategies where tokens must appear in pairs ====
|
||||
* ======================================================
|
||||
*
|
||||
* Strategies detecting issues reported in ANTLR where a character was expected to appear in a
|
||||
* pair with another character. This is like open and close parans. Note that some are left
|
||||
* protected to support unit testing.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Template class for checking that two tokens appear in pairs.
|
||||
*
|
||||
* <p>
|
||||
* Template class for message simplification strategies that check for an equal number of
|
||||
* occurrences for two characters like "(" and ")".
|
||||
* </p>
|
||||
*/
|
||||
protected static class TokenPairTemplateMessageSimplifierStrategy
|
||||
implements PreprocIssueMessageSimplifierStrategy {
|
||||
|
||||
private final String token1;
|
||||
private final String token2;
|
||||
|
||||
/**
|
||||
* Create a new token pair issue detector.
|
||||
*
|
||||
* @param newToken1 The opening token like "(".
|
||||
* @param newToken2 The closing token like ")".
|
||||
*/
|
||||
public TokenPairTemplateMessageSimplifierStrategy(String newToken1, String newToken2) {
|
||||
token1 = newToken1;
|
||||
token2 = newToken2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<IssueMessageSimplification> simplify(String message) {
|
||||
String messageContent = getOffendingArea(message);
|
||||
|
||||
int count1 = SyntaxUtil.getCount(messageContent, token1);
|
||||
int count2 = SyntaxUtil.getCount(messageContent, token2);
|
||||
|
||||
if (count1 == count2) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String missingToken;
|
||||
if (count1 < count2) {
|
||||
missingToken = token1;
|
||||
} else {
|
||||
missingToken = token2;
|
||||
}
|
||||
|
||||
String newMessage = String.format(
|
||||
getLocalStr("editor.status.missing.default")
|
||||
.replace("%c", "%s"), missingToken);
|
||||
|
||||
return Optional.of(
|
||||
new IssueMessageSimplification(newMessage)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy for unbalanced curly braces.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createUnbalancedCurlyStrategy() {
|
||||
return new TokenPairTemplateMessageSimplifierStrategy("{", "}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy for unbalanced chevrons.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createUnbalancedChevStrategy() {
|
||||
return new TokenPairTemplateMessageSimplifierStrategy("<", ">");
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy for unbalanced parens.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createUnbalancedParenStrategy() {
|
||||
return new TokenPairTemplateMessageSimplifierStrategy("(", ")");
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* ==== Strategies using regex against the ANTLR error message ====
|
||||
* ================================================================
|
||||
*
|
||||
* Strategies detecting issues reported in ANTLR by using a regex over the ANTLR error message.
|
||||
* Note that some are left protected to support unit testing.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Strategy that cleans up errors based on a regex matching the error message.
|
||||
*/
|
||||
protected static class RegexTemplateMessageSimplifierStrategy
|
||||
implements PreprocIssueMessageSimplifierStrategy {
|
||||
|
||||
private final Pattern pattern;
|
||||
private final String hintTemplate;
|
||||
|
||||
/**
|
||||
* Create a new instance of this strategy.
|
||||
*
|
||||
* @param newRegex The regex that should be matched in order to activate this strategy.
|
||||
* @param newHintTemplate template string with a "%s" where the "offending snippet of code" can
|
||||
* be inserted where the resulting rendered template can be used as an error hint for the
|
||||
* user. For example, "Invalid identifier near %s" may be rendered to the user like "Syntax
|
||||
* error. Hint: Invalid identifier near ,1a);".
|
||||
*/
|
||||
public RegexTemplateMessageSimplifierStrategy(String newRegex, String newHintTemplate) {
|
||||
pattern = Pattern.compile(newRegex);
|
||||
hintTemplate = newHintTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<IssueMessageSimplification> simplify(String message) {
|
||||
if (pattern.matcher(message).find()) {
|
||||
String newMessage = String.format(
|
||||
hintTemplate,
|
||||
getOffendingArea(message)
|
||||
);
|
||||
|
||||
return Optional.of(
|
||||
new IssueMessageSimplification(newMessage, getAttributeToPrior())
|
||||
);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this issue should be attributed to the prior token.
|
||||
*
|
||||
* @return True if should be attributed to prior token. False otherwise.
|
||||
*/
|
||||
public boolean getAttributeToPrior() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut to create a regex matcher with a localized error message.
|
||||
*
|
||||
* @param regex The regex to match.
|
||||
* @param localStr The localized string identifier to use when the regex matches.
|
||||
* @return Newly created simplifier strategy.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createRegexStrategyUsingLocalStr(String regex,
|
||||
String localStr) {
|
||||
|
||||
return new RegexTemplateMessageSimplifierStrategy(
|
||||
regex,
|
||||
getLocalStr(localStr)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy for invalid parameter.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createErrorOnParameterStrategy() {
|
||||
return createRegexStrategyUsingLocalStr(
|
||||
"([a-zA-Z0-9_]+\\s*,|[a-zA-Z0-9_]+\\)|\\([^\\)]+)",
|
||||
"editor.status.bad.parameter"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy for missing method name.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createMethodMissingNameStrategy() {
|
||||
return createRegexStrategyUsingLocalStr(
|
||||
"[a-zA-Z0-9_]+\\s*\\(.*\\)\\s*\\{",
|
||||
"editor.status.missing.name"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy for missing class name.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createMissingClassNameStrategy() {
|
||||
return createRegexStrategyUsingLocalStr(
|
||||
".*(class|interface)\\s*[a-zA-Z0-9_]*\\s+(extends|implements|<.*>)?\\s*[a-zA-Z0-9_]*\\s*\\{.*",
|
||||
"editor.status.missing.name"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy for invalid identifier.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createInvalidIdentifierStrategy() {
|
||||
return createRegexStrategyUsingLocalStr(
|
||||
"([.\\s]*[0-9]+[a-zA-Z_<>]+[0-9a-zA-Z_<>]*|\\s+\\d+[a-zA-Z_<>]+|[0-9a-zA-Z_<>]+\\s+[0-9]+)",
|
||||
"editor.status.bad.identifier"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy for invalid variable declaration.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createVariableDeclarationMissingTypeStrategy() {
|
||||
return createRegexStrategyUsingLocalStr(
|
||||
"[a-zA-Z_]+[0-9a-zA-Z_]*\\s*(=[^\n\\n;]*)?;'?$",
|
||||
"editor.status.missing.type"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy for invalid assignment.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createInvalidAssignmentStrategy() {
|
||||
return createRegexStrategyUsingLocalStr(
|
||||
"[.\\n]*[0-9a-zA-Z\\_<>]+\\s*=[\\s';]*$",
|
||||
"editor.status.bad.assignment"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy for invalid generic.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createInvalidGenericDefinitionStrategy() {
|
||||
return createRegexStrategyUsingLocalStr(
|
||||
"<>'?$",
|
||||
"editor.status.bad.generic"
|
||||
);
|
||||
}
|
||||
|
||||
/* ==========================
|
||||
* ==== Other Strategies ====
|
||||
* ==========================
|
||||
*
|
||||
* Strategies that cannot work using some of the more generalized methods implemented above.
|
||||
* Note that some are protected to support unit testing.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Strategy to catch a missing curly that got caught by ANTLR at the start of a statement.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createMissingCurlyAtStartSimplifierStrategy() {
|
||||
|
||||
return message -> {
|
||||
boolean matches = message.endsWith("expecting {'throws', '{'}");
|
||||
matches = matches || message.endsWith("expecting {'throws', '{', '[', ';'}");
|
||||
|
||||
if (!matches) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(new IssueMessageSimplification(
|
||||
getLocalStr("editor.status.missing.left_curly_bracket")
|
||||
));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy to catch a missing curly at a semicolon.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createMissingCurlyAtSemicolonSimplifierStrategy() {
|
||||
return message -> {
|
||||
if (!message.equals("missing ';' at '{'")) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(new IssueMessageSimplification(
|
||||
getLocalStr("editor.status.missing.right_curly_bracket")
|
||||
));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy to check for an error indicating that an identifier was expected but not given.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createMissingIdentifierSimplifierStrategy() {
|
||||
return message -> {
|
||||
if (message.toLowerCase().contains("missing identifier at")) {
|
||||
String newMessage = String.format(
|
||||
getLocalStr("editor.status.missing.name"),
|
||||
message.replace("missing Identifier at", "")
|
||||
);
|
||||
return Optional.of(
|
||||
new IssueMessageSimplification(newMessage)
|
||||
);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy to handle missing token messages.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createKnownMissingSimplifierStrategy() {
|
||||
final Pattern parsePattern = Pattern.compile(".*missing '(.*)' at .*");
|
||||
return message -> {
|
||||
if (message.toLowerCase().contains("missing")) {
|
||||
String missingPiece;
|
||||
Matcher matcher = parsePattern.matcher(message);
|
||||
if (matcher.find()) {
|
||||
missingPiece = matcher.group(1);
|
||||
} else {
|
||||
missingPiece = "character";
|
||||
}
|
||||
|
||||
String langTemplate = getLocalStr("editor.status.missing.default")
|
||||
.replace("%c", "%s");
|
||||
|
||||
String newMessage = String.format(langTemplate, missingPiece);
|
||||
|
||||
return Optional.of(new IssueMessageSimplification(newMessage));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy to handle extraneous input messages.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createExtraneousInputSimplifierStrategy() {
|
||||
return message -> {
|
||||
if (message.toLowerCase().contains("extraneous")) {
|
||||
String innerMsg = getOffendingArea(message);
|
||||
|
||||
String newMessageOuter = getLocalStr("editor.status.extraneous");
|
||||
String newMessage = String.format(newMessageOuter, innerMsg);
|
||||
|
||||
return Optional.of(
|
||||
new IssueMessageSimplification(newMessage)
|
||||
);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy to explain a mismatched input issue.
|
||||
*/
|
||||
protected PreprocIssueMessageSimplifierStrategy createMismatchedInputSimplifierStrategy() {
|
||||
final Pattern parser = Pattern.compile("mismatched input '(.*)' expecting ");
|
||||
return message -> {
|
||||
if (message.toLowerCase().contains("mismatched input")) {
|
||||
Matcher matcher = parser.matcher(message);
|
||||
|
||||
String newMessage = String.format(
|
||||
getLocalStr("editor.status.mismatched"),
|
||||
matcher.find() ? matcher.group(1) : message
|
||||
);
|
||||
|
||||
return Optional.of(
|
||||
new IssueMessageSimplification(
|
||||
newMessage
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Default strategy to use if other message simplification strategies have failed.
|
||||
*/
|
||||
protected static class DefaultMessageSimplifier implements PreprocIssueMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public Optional<IssueMessageSimplification> simplify(String message) {
|
||||
if (message.contains("viable alternative")) {
|
||||
String newMessage = String.format(
|
||||
getLocalizedGenericError("%s"),
|
||||
getOffendingArea(message)
|
||||
);
|
||||
return Optional.of(
|
||||
new IssueMessageSimplification(newMessage)
|
||||
);
|
||||
} else {
|
||||
return Optional.of(
|
||||
new IssueMessageSimplification(message)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue;
|
||||
|
||||
|
||||
import processing.mode.java.preproc.issue.strategy.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
|
||||
/**
|
||||
* Facade that tries to create a better error message for syntax issues in input source.
|
||||
*
|
||||
* <p>
|
||||
* Facade that interprets error messages from ANTLR in an attempt to generate an improved error
|
||||
* message when describing grammatically incorrect input. This is distinct from compiler errors
|
||||
* caused after generating an AST.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Note that this is distinct from the {CompileErrorMessageSimplifier}. This operates on issues
|
||||
* caused in parsing and services all users whereas the {CompileErrorMessageSimplifier} only
|
||||
* operates on issues generated after preprocessing has been successful.
|
||||
* </p>
|
||||
*/
|
||||
public class PreprocessIssueMessageSimplifierFacade {
|
||||
|
||||
private static AtomicReference<PreprocessIssueMessageSimplifierFacade> instance = new AtomicReference<>();
|
||||
|
||||
private List<PreprocIssueMessageSimplifierStrategy> strategies;
|
||||
|
||||
/**
|
||||
* Get a shared instance of this singleton.
|
||||
*
|
||||
* @return Shared instance of this singleton, creating that shared instance if one did not exist
|
||||
* previously.
|
||||
*/
|
||||
public static PreprocessIssueMessageSimplifierFacade get() {
|
||||
instance.compareAndSet(null, new PreprocessIssueMessageSimplifierFacade());
|
||||
return instance.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new syntax issue message simplifier with the default simplifier strategies.
|
||||
*/
|
||||
private PreprocessIssueMessageSimplifierFacade() {
|
||||
strategies = new ArrayList<>();
|
||||
strategies.add(new MissingCurlyAtStartMessageSimplifierStrategy());
|
||||
strategies.add(new MissingCurlyAtSemicolonMessageSimplifierStrategy());
|
||||
strategies.add(new MissingGenericTypeMessageSimplifierStrategy());
|
||||
strategies.add(new MissingIdentifierMessageSimplifierStrategy());
|
||||
strategies.add(new KnownMissingMessageSimplifierStrategy());
|
||||
strategies.add(new ExtraneousInputMessageSimplifierStrategy());
|
||||
strategies.add(new MismatchedInputMessageSimplifierStrategy());
|
||||
strategies.add(new AssignmentMessageSimplifierStrategy());
|
||||
strategies.add(new MissingVariableNameMessageSimplifierStrategy());
|
||||
strategies.add(new BadIdentifierMessageSimplifierStrategy());
|
||||
strategies.add(new MissingClassNameMessageSimplifierStrategy());
|
||||
strategies.add(new MissingMethodNameMessageSimplifierStrategy());
|
||||
strategies.add(new BadParamMessageSimplifierStrategy());
|
||||
strategies.add(new MissingDoubleQuoteMessageSimplifierStrategy());
|
||||
strategies.add(new MissingSingleQuoteMessageSimplifierStrategy());
|
||||
strategies.add(new MissingParenMessageSimplifierStrategy());
|
||||
strategies.add(new MissingChevMessageSimplifierStrategy());
|
||||
strategies.add(new MissingCurlyMessageSimplifierStrategy());
|
||||
strategies.add(new DefaultMessageSimplifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to improve an error message.
|
||||
*
|
||||
* @param originalMessage Error message generated from ANTLR.
|
||||
* @return An improved error message or the originalMessage if no improvements could be made.
|
||||
*/
|
||||
public IssueMessageSimplification simplify(String originalMessage) {
|
||||
//System.err.println(originalMessage);
|
||||
Optional<IssueMessageSimplification> matching = strategies.stream()
|
||||
.map((x) -> x.simplify(originalMessage))
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.findFirst();
|
||||
|
||||
return matching.orElse(new IssueMessageSimplification(originalMessage));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
|
||||
/**
|
||||
* Strategy to describe an issue in an assignment.
|
||||
*/
|
||||
public class AssignmentMessageSimplifierStrategy extends RegexTemplateMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public String getRegexPattern() {
|
||||
return "[.\\n]*[0-9a-zA-Z\\_<>]+\\s*=[\\s';]*$";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHintTemplate() {
|
||||
return MessageSimplifierUtil.getLocalStr("editor.status.bad.assignment");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
/**
|
||||
* Strategy to describe issue in an identifier name like an identifier starting with a digit.
|
||||
*/
|
||||
public class BadIdentifierMessageSimplifierStrategy extends RegexTemplateMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public String getRegexPattern() {
|
||||
return "([.\\s]*[0-9]+[a-zA-Z_<>]+[0-9a-zA-Z_<>]*|\\s+\\d+[a-zA-Z_<>]+|[0-9a-zA-Z_<>]+\\s+[0-9]+)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHintTemplate() {
|
||||
return MessageSimplifierUtil.getLocalStr(
|
||||
"editor.status.bad.identifier"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
/**
|
||||
* Strategy to check for an error in specifying a parameter value.
|
||||
*/
|
||||
public class BadParamMessageSimplifierStrategy
|
||||
extends RegexTemplateMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public String getRegexPattern() {
|
||||
return "([a-zA-Z0-9_]+\\s*,|[a-zA-Z0-9_]+\\)|\\([^\\)]+)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHintTemplate() {
|
||||
return MessageSimplifierUtil.getLocalStr("editor.status.bad.parameter");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
import processing.mode.java.preproc.issue.IssueMessageSimplification;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/**
|
||||
* Default strategy to use if other message simplification strategies have failed.
|
||||
*/
|
||||
public class DefaultMessageSimplifier implements PreprocIssueMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public Optional<IssueMessageSimplification> simplify(String message) {
|
||||
if (message.contains("viable alternative")) {
|
||||
String newMessage = String.format(
|
||||
MessageSimplifierUtil.getLocalizedGenericError("%s"),
|
||||
MessageSimplifierUtil.getOffendingArea(message)
|
||||
);
|
||||
return Optional.of(
|
||||
new IssueMessageSimplification(newMessage)
|
||||
);
|
||||
} else {
|
||||
return Optional.of(
|
||||
new IssueMessageSimplification(message)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
import processing.app.Language;
|
||||
import processing.mode.java.preproc.issue.IssueMessageSimplification;
|
||||
import processing.mode.java.preproc.code.SyntaxUtil;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/**
|
||||
* Strategy to check to make sure that the number of occurrences of a token are even.
|
||||
*
|
||||
* <p>
|
||||
* Strategy to ensure that there are an even number of tokens like even number of double quotes
|
||||
* for example.
|
||||
* </p>
|
||||
*/
|
||||
public abstract class EvenCountTemplateMessageSimplifierStrategy
|
||||
implements PreprocIssueMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public Optional<IssueMessageSimplification> simplify(String message) {
|
||||
String messageContent = MessageSimplifierUtil.getOffendingArea(message);
|
||||
|
||||
if (getFilter().isPresent()) {
|
||||
messageContent = messageContent.replace(getFilter().get(), "");
|
||||
}
|
||||
|
||||
int count = SyntaxUtil.getCount(messageContent, getToken());
|
||||
|
||||
if (count % 2 == 0) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
String newMessage = String.format(
|
||||
MessageSimplifierUtil.getLocalStr("editor.status.missing.default").replace("%c", "%s"),
|
||||
getToken()
|
||||
);
|
||||
return Optional.of(
|
||||
new IssueMessageSimplification(newMessage)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the token that should be counted.
|
||||
*
|
||||
* @return The token whose occurrences should be even.
|
||||
*/
|
||||
public abstract String getToken();
|
||||
|
||||
/**
|
||||
* Get the text that should be removed before counting.
|
||||
*
|
||||
* @return An optional string whose occurrences will be removed prior to counting.
|
||||
*/
|
||||
public Optional<String> getFilter() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
import processing.mode.java.preproc.issue.IssueMessageSimplification;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/**
|
||||
* Strategy to handle extraneous input messages.
|
||||
*/
|
||||
public class ExtraneousInputMessageSimplifierStrategy
|
||||
implements PreprocIssueMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public Optional<IssueMessageSimplification> simplify(String message) {
|
||||
if (message.toLowerCase().contains("extraneous")) {
|
||||
String innerMsg = MessageSimplifierUtil.getOffendingArea(message);
|
||||
|
||||
String newMessageOuter = MessageSimplifierUtil.getLocalStr("editor.status.extraneous");
|
||||
String newMessage = String.format(newMessageOuter, innerMsg);
|
||||
|
||||
return Optional.of(
|
||||
new IssueMessageSimplification(newMessage)
|
||||
);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
import processing.mode.java.preproc.issue.IssueMessageSimplification;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
* Strategy to handle missing token messages.
|
||||
*/
|
||||
public class KnownMissingMessageSimplifierStrategy implements PreprocIssueMessageSimplifierStrategy {
|
||||
|
||||
private static final String PARSE_PATTERN_STR = ".*missing '(.*)' at .*";
|
||||
|
||||
private final Pattern parsePattern;
|
||||
|
||||
public KnownMissingMessageSimplifierStrategy() {
|
||||
parsePattern = Pattern.compile(PARSE_PATTERN_STR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<IssueMessageSimplification> simplify(String message) {
|
||||
if (message.toLowerCase().contains("missing")) {
|
||||
String missingPiece;
|
||||
Matcher matcher = parsePattern.matcher(message);
|
||||
if (matcher.find()) {
|
||||
missingPiece = matcher.group(1);
|
||||
} else {
|
||||
missingPiece = "character";
|
||||
}
|
||||
|
||||
String langTemplate = MessageSimplifierUtil.getLocalStr("editor.status.missing.default")
|
||||
.replace("%c", "%s");
|
||||
|
||||
String newMessage = String.format(langTemplate, missingPiece);
|
||||
|
||||
return Optional.of(new IssueMessageSimplification(newMessage));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
import processing.app.Language;
|
||||
import processing.app.Platform;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
/**
|
||||
* Convenience functions useful for generating simplified messages.
|
||||
*/
|
||||
public class MessageSimplifierUtil {
|
||||
|
||||
/**
|
||||
* Get the snippet of "offending code" from an error message if given.
|
||||
*
|
||||
* @param area The area from which to extract the offending code.
|
||||
* @return The offending code described in the error message or the original message if the subset
|
||||
* describing the offending code could not be found.
|
||||
*/
|
||||
public static String getOffendingArea(String area) {
|
||||
return getOffendingArea(area, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the snippet of "offending code" from an error message if given.
|
||||
*
|
||||
* @param area The area from which to extract the offending code.
|
||||
* @param removeNewline Flag indicating if newlines should be removed or not.
|
||||
* @return The offending code described in the error message or the original message if the subset
|
||||
* describing the offending code could not be found.
|
||||
*/
|
||||
public static String getOffendingArea(String area, boolean removeNewline) {
|
||||
if (!area.contains("viable alternative")) {
|
||||
return area;
|
||||
}
|
||||
|
||||
String content = area.replace("no viable alternative at input \'", "");
|
||||
|
||||
if (removeNewline) {
|
||||
String[] contentLines = content.replace("\n", "\\n").split("\\\\n");
|
||||
content = contentLines[contentLines.length - 1];
|
||||
}
|
||||
|
||||
if (content.endsWith("'")) {
|
||||
return content.substring(0, content.length() - 1);
|
||||
} else {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an generic error message.
|
||||
*
|
||||
* @param unlocalized The unlocalized string. Will be included in resulting message but with
|
||||
* surrounding localized text.
|
||||
* @return Semi-localized message.
|
||||
*/
|
||||
public static String getLocalizedGenericError(String unlocalized) {
|
||||
String template = getLocalStr("editor.status.error_on");
|
||||
return String.format(template, unlocalized);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a localized template string.
|
||||
*
|
||||
* @param stringName Name of the template.
|
||||
* @return The template's contents prior to rendering.
|
||||
*/
|
||||
public static String getLocalStr(String stringName) {
|
||||
String errStr;
|
||||
String retStr;
|
||||
|
||||
if (Platform.isInit()) {
|
||||
errStr = Language.text("editor.status.error.syntax");
|
||||
retStr = Language.text(stringName);
|
||||
} else {
|
||||
errStr = DefaultErrorLocalStrSet.get().get("editor.status.error.syntax").orElse("Error");
|
||||
retStr = DefaultErrorLocalStrSet.get().get(stringName).orElse(stringName);
|
||||
}
|
||||
|
||||
return String.format(errStr, retStr);
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
import processing.mode.java.preproc.issue.IssueMessageSimplification;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
* Strategy to explain a mismatched input issue.
|
||||
*/
|
||||
public class MismatchedInputMessageSimplifierStrategy implements PreprocIssueMessageSimplifierStrategy {
|
||||
|
||||
private static final String PARSER_STR = "mismatched input '(.*)' expecting ";
|
||||
private final Pattern parser;
|
||||
|
||||
/**
|
||||
* Create a new strategy for mismatched input.
|
||||
*/
|
||||
public MismatchedInputMessageSimplifierStrategy() {
|
||||
parser = Pattern.compile(PARSER_STR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<IssueMessageSimplification> simplify(String message) {
|
||||
if (message.toLowerCase().contains("mismatched input")) {
|
||||
Matcher matcher = parser.matcher(message);
|
||||
|
||||
String newMessage = String.format(
|
||||
MessageSimplifierUtil.getLocalStr("editor.status.mismatched"),
|
||||
matcher.find() ? matcher.group(1) : message
|
||||
);
|
||||
|
||||
return Optional.of(
|
||||
new IssueMessageSimplification(
|
||||
newMessage
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
/**
|
||||
* Strategy to check for a missing chevron.
|
||||
*/
|
||||
public class MissingChevMessageSimplifierStrategy
|
||||
extends TokenPairTemplateMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public String getToken1() {
|
||||
return "<";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getToken2() {
|
||||
return ">";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
/**
|
||||
* Strategy to check for a class definition without a name.
|
||||
*/
|
||||
public class MissingClassNameMessageSimplifierStrategy extends RegexTemplateMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public String getRegexPattern() {
|
||||
return ".*(class|interface)\\s*[a-zA-Z0-9_]*\\s+(extends|implements|<.*>)?\\s*[a-zA-Z0-9_]*\\s*\\{.*";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHintTemplate() {
|
||||
return MessageSimplifierUtil.getLocalStr("editor.status.missing.name");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
import processing.mode.java.preproc.issue.IssueMessageSimplification;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/**
|
||||
* Strategy to catch a missing curly at a semicolon.
|
||||
*/
|
||||
public class MissingCurlyAtSemicolonMessageSimplifierStrategy
|
||||
implements PreprocIssueMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public Optional<IssueMessageSimplification> simplify(String message) {
|
||||
if (!message.equals("missing ';' at '{'")) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(new IssueMessageSimplification(
|
||||
MessageSimplifierUtil.getLocalStr("editor.status.missing.right_curly_bracket")
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
import processing.mode.java.preproc.issue.IssueMessageSimplification;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class MissingCurlyAtStartMessageSimplifierStrategy
|
||||
implements PreprocIssueMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public Optional<IssueMessageSimplification> simplify(String message) {
|
||||
boolean matches = message.endsWith("expecting {'throws', '{'}");
|
||||
matches = matches || message.endsWith("expecting {'throws', '{', '[', ';'}");
|
||||
|
||||
if (!matches) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(new IssueMessageSimplification(
|
||||
MessageSimplifierUtil.getLocalStr("editor.status.missing.left_curly_bracket")
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
|
||||
/**
|
||||
* Strategy to check that every open curly has a corresponding close curly.
|
||||
*/
|
||||
public class MissingCurlyMessageSimplifierStrategy
|
||||
extends TokenPairTemplateMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public String getToken1() {
|
||||
return "{";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getToken2() {
|
||||
return "}";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/**
|
||||
* Strategy to check that double quotes are balanced.
|
||||
*/
|
||||
public class MissingDoubleQuoteMessageSimplifierStrategy
|
||||
extends EvenCountTemplateMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public String getToken() {
|
||||
return "\"";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getFilter() {
|
||||
return Optional.of("\\\"");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
|
||||
/**
|
||||
* Missing type in a generic.
|
||||
*/
|
||||
public class MissingGenericTypeMessageSimplifierStrategy
|
||||
extends RegexTemplateMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public String getRegexPattern() {
|
||||
return "<>'?$";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHintTemplate() {
|
||||
return MessageSimplifierUtil.getLocalStr("editor.status.bad.generic");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
import processing.mode.java.preproc.issue.IssueMessageSimplification;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/**
|
||||
* Strategy to check for an error indicating that an identifier was expected but not given.
|
||||
*/
|
||||
public class MissingIdentifierMessageSimplifierStrategy
|
||||
implements PreprocIssueMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public Optional<IssueMessageSimplification> simplify(String message) {
|
||||
if (message.toLowerCase().contains("missing identifier at")) {
|
||||
String newMessage = String.format(
|
||||
MessageSimplifierUtil.getLocalStr("editor.status.missing.name"),
|
||||
message.replace("missing Identifier at", "")
|
||||
);
|
||||
return Optional.of(
|
||||
new IssueMessageSimplification(newMessage)
|
||||
);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
|
||||
/**
|
||||
* Strategy to check for a method declaration without a name or return type.
|
||||
*/
|
||||
public class MissingMethodNameMessageSimplifierStrategy
|
||||
extends RegexTemplateMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public String getRegexPattern() {
|
||||
return "[a-zA-Z0-9_]+\\s*\\(.*\\)\\s*\\{";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHintTemplate() {
|
||||
return MessageSimplifierUtil.getLocalStr("editor.status.missing.name");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
|
||||
/**
|
||||
* Strategy to check for an opening parentheses without a close parantheses.
|
||||
*/
|
||||
public class MissingParenMessageSimplifierStrategy
|
||||
extends TokenPairTemplateMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public String getToken1() {
|
||||
return "(";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getToken2() {
|
||||
return ")";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/**
|
||||
* Strategy to check for an open single quote without a corresponding close single quote.
|
||||
*/
|
||||
public class MissingSingleQuoteMessageSimplifierStrategy
|
||||
extends EvenCountTemplateMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public String getToken() {
|
||||
return "\'";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getFilter() {
|
||||
return Optional.of("\\'");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
import processing.app.Language;
|
||||
|
||||
/**
|
||||
* Strategy that checks for a variable decalaration missing its name or its type.
|
||||
*/
|
||||
public class MissingVariableNameMessageSimplifierStrategy
|
||||
extends RegexTemplateMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public String getRegexPattern() {
|
||||
return "[a-zA-Z_]+[0-9a-zA-Z_]*\\s*(=[^\n\\n;]*)?;'?$";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHintTemplate() {
|
||||
return MessageSimplifierUtil.getLocalStr("editor.status.missing.type");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
import processing.mode.java.preproc.issue.IssueMessageSimplification;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/**
|
||||
* Interface for strategies that improve preprocess error messages before showing them to the user.
|
||||
*/
|
||||
public interface PreprocIssueMessageSimplifierStrategy {
|
||||
|
||||
/**
|
||||
* Attempt to simplify an error message.
|
||||
*
|
||||
* @param message The message to be simplified.
|
||||
* @return An optional with an improved message or an empty optional if no improvements could be
|
||||
* made by this strategy.
|
||||
*/
|
||||
Optional<IssueMessageSimplification> simplify(String message);
|
||||
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
import processing.mode.java.preproc.issue.IssueMessageSimplification;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
* Strategy that cleans up errors based on a regex matching the error message.
|
||||
*/
|
||||
public abstract class RegexTemplateMessageSimplifierStrategy
|
||||
implements PreprocIssueMessageSimplifierStrategy {
|
||||
|
||||
private Pattern pattern;
|
||||
|
||||
/**
|
||||
* Create a new instance of this strategy.
|
||||
*/
|
||||
public RegexTemplateMessageSimplifierStrategy() {
|
||||
pattern = Pattern.compile(getRegexPattern());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<IssueMessageSimplification> simplify(String message) {
|
||||
if (pattern.matcher(message).find()) {
|
||||
String newMessage = String.format(
|
||||
getHintTemplate(),
|
||||
MessageSimplifierUtil.getOffendingArea(message)
|
||||
);
|
||||
|
||||
return Optional.of(
|
||||
new IssueMessageSimplification(newMessage, getAttributeToPrior())
|
||||
);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this issue should be attributed to the prior token.
|
||||
*
|
||||
* @return True if should be attributed to prior token. False otherwise.
|
||||
*/
|
||||
public boolean getAttributeToPrior() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the regex that should be matched against the error message for this strategy to apply.
|
||||
*
|
||||
* @return The regex that should be matched in order to activate this strategy.
|
||||
*/
|
||||
public abstract String getRegexPattern();
|
||||
|
||||
/**
|
||||
* Get the hint template for this strategy.
|
||||
*
|
||||
* <p>
|
||||
* Get a template string with a "%s" where the "offending snippet of code" can be inserted where
|
||||
* the resulting rendered template can be used as an error hint for the user. For example,
|
||||
* "Invalid identifier near %s" may be rendered to the user like "Syntax error. Hint: Invalid
|
||||
* identifier near ,1a);" for example.
|
||||
* </p>
|
||||
*
|
||||
* @return The rendered hint template.
|
||||
*/
|
||||
public abstract String getHintTemplate();
|
||||
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc.issue.strategy;
|
||||
|
||||
import processing.app.Language;
|
||||
import processing.mode.java.preproc.issue.IssueMessageSimplification;
|
||||
import processing.mode.java.preproc.code.SyntaxUtil;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/**
|
||||
* Template class for checking that two tokens appear in pairs.
|
||||
*
|
||||
* <p>
|
||||
* Template class for message simplification strategies that check for an equal number of
|
||||
* occurrences for two characters like "(" and ")".
|
||||
* </p>
|
||||
*/
|
||||
public abstract class TokenPairTemplateMessageSimplifierStrategy
|
||||
implements PreprocIssueMessageSimplifierStrategy {
|
||||
|
||||
@Override
|
||||
public Optional<IssueMessageSimplification> simplify(String message) {
|
||||
String messageContent = MessageSimplifierUtil.getOffendingArea(message);
|
||||
|
||||
int count1 = SyntaxUtil.getCount(messageContent, getToken1());
|
||||
int count2 = SyntaxUtil.getCount(messageContent, getToken2());
|
||||
|
||||
if (count1 == count2) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String missingToken;
|
||||
if (count1 < count2) {
|
||||
missingToken = getToken1();
|
||||
} else {
|
||||
missingToken = getToken2();
|
||||
}
|
||||
|
||||
String newMessage = String.format(
|
||||
MessageSimplifierUtil.getLocalStr("editor.status.missing.default")
|
||||
.replace("%c", "%s"), missingToken);
|
||||
|
||||
return Optional.of(
|
||||
new IssueMessageSimplification(newMessage)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first token in the pair.
|
||||
*
|
||||
* @return The first token whose occurrences should be counted.
|
||||
*/
|
||||
public abstract String getToken1();
|
||||
|
||||
|
||||
/**
|
||||
* Get the second token in the pair.
|
||||
*
|
||||
* @return The second token whose occurrences should be counted.
|
||||
*/
|
||||
public abstract String getToken2();
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user