mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-04 14:55:41 +02:00
Use generics.
This commit is contained in:
parent
bfda3445f7
commit
ec5204c969
1 changed files with 71 additions and 116 deletions
|
@ -34,7 +34,7 @@ public class Problem implements IProblem {
|
||||||
|
|
||||||
private String message = null;
|
private String message = null;
|
||||||
|
|
||||||
public Problem( int id, int start, int end, int line, char[] file, String[] arg,
|
public Problem(int id, int start, int end, int line, char[] file, String[] arg,
|
||||||
boolean warn, boolean error) {
|
boolean warn, boolean error) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.sourceStart = start;
|
this.sourceStart = start;
|
||||||
|
@ -95,159 +95,114 @@ public class Problem implements IProblem {
|
||||||
return isWarning;
|
return isWarning;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static final Map errorMessages;
|
protected static final Map<Integer, String> errorMessages;
|
||||||
static {
|
static {
|
||||||
errorMessages = new HashMap();
|
errorMessages = new HashMap<Integer, String>();
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_UNIQUE_NAME_PREDEFINED,
|
||||||
new Integer( IProblem.SEMANTIC_UNIQUE_NAME_PREDEFINED),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.uniqueNamePredefined")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.uniqueNamePredefined")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_NAME_NOT_FOUND,
|
||||||
new Integer( IProblem.SEMANTIC_NAME_NOT_FOUND),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.nameNotFound")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.nameNotFound")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_NAME_NOT_PROVIDED,
|
||||||
new Integer( IProblem.SEMANTIC_NAME_NOT_PROVIDED),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.nameNotProvided")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.nameNotProvided")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_INVALID_CONVERSION_TYPE ,
|
||||||
new Integer( IProblem.SEMANTIC_INVALID_CONVERSION_TYPE ),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.invalidConversionType")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.invalidConversionType")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_MALFORMED_EXPRESSION ,
|
||||||
new Integer( IProblem.SEMANTIC_MALFORMED_EXPRESSION ),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.malformedExpression")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.malformedExpression")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_AMBIGUOUS_LOOKUP ,
|
||||||
new Integer( IProblem.SEMANTIC_AMBIGUOUS_LOOKUP ),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.ambiguousLookup")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.ambiguousLookup")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_INVALID_TYPE ,
|
||||||
new Integer( IProblem.SEMANTIC_INVALID_TYPE ),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidType")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidType")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_CIRCULAR_INHERITANCE ,
|
||||||
new Integer( IProblem.SEMANTIC_CIRCULAR_INHERITANCE ),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.circularInheritance")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.circularInheritance")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_INVALID_OVERLOAD ,
|
||||||
new Integer( IProblem.SEMANTIC_INVALID_OVERLOAD ),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidOverload")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidOverload")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_INVALID_TEMPLATE ,
|
||||||
new Integer( IProblem.SEMANTIC_INVALID_TEMPLATE ),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidTemplate")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidTemplate")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_INVALID_USING ,
|
||||||
new Integer( IProblem.SEMANTIC_INVALID_USING ),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidUsing")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidUsing")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_BAD_VISIBILITY ,
|
||||||
new Integer( IProblem.SEMANTIC_BAD_VISIBILITY ),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.badVisibility")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.badVisibility")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_UNABLE_TO_RESOLVE_FUNCTION ,
|
||||||
new Integer( IProblem.SEMANTIC_UNABLE_TO_RESOLVE_FUNCTION ),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.unableToResolveFunction")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.unableToResolveFunction")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_INVALID_TEMPLATE_ARGUMENT ,
|
||||||
new Integer( IProblem.SEMANTIC_INVALID_TEMPLATE_ARGUMENT ),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidTemplateArgument")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidTemplateArgument")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_INVALID_TEMPLATE_PARAMETER ,
|
||||||
new Integer( IProblem.SEMANTIC_INVALID_TEMPLATE_PARAMETER ),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidTemplateParameter")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidTemplateParameter")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_REDECLARED_TEMPLATE_PARAMETER ,
|
||||||
new Integer( IProblem.SEMANTIC_REDECLARED_TEMPLATE_PARAMETER ),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.redeclaredTemplateParameter")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.redeclaredTemplateParameter")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SEMANTIC_RECURSIVE_TEMPLATE_INSTANTIATION ,
|
||||||
new Integer( IProblem.SEMANTIC_RECURSIVE_TEMPLATE_INSTANTIATION ),
|
|
||||||
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.recursiveTemplateInstantiation")); //$NON-NLS-1$
|
ParserMessages.getString("ASTProblemFactory.error.semantic.pst.recursiveTemplateInstantiation")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.PREPROCESSOR_POUND_ERROR,
|
||||||
new Integer(IProblem.PREPROCESSOR_POUND_ERROR),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.preproc.error")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.preproc.error")); //$NON-NLS-1$
|
||||||
errorMessages.put(new Integer(IProblem.PREPROCESSOR_POUND_WARNING), ParserMessages
|
errorMessages.put(IProblem.PREPROCESSOR_POUND_WARNING,
|
||||||
.getString("ScannerProblemFactory.error.preproc.warning")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.preproc.warning")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND,
|
||||||
new Integer(IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.preproc.inclusionNotFound")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.preproc.inclusionNotFound")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.PREPROCESSOR_DEFINITION_NOT_FOUND,
|
||||||
new Integer(IProblem.PREPROCESSOR_DEFINITION_NOT_FOUND),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.preproc.definitionNotFound")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.preproc.definitionNotFound")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.PREPROCESSOR_INVALID_MACRO_DEFN,
|
||||||
new Integer(IProblem.PREPROCESSOR_INVALID_MACRO_DEFN),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.preproc.invalidMacroDefn")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.preproc.invalidMacroDefn")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.PREPROCESSOR_INVALID_MACRO_REDEFN,
|
||||||
new Integer(IProblem.PREPROCESSOR_INVALID_MACRO_REDEFN),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.preproc.invalidMacroRedefn")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.preproc.invalidMacroRedefn")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.PREPROCESSOR_UNBALANCE_CONDITION,
|
||||||
new Integer(IProblem.PREPROCESSOR_UNBALANCE_CONDITION),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.preproc.unbalancedConditional")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.preproc.unbalancedConditional")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.PREPROCESSOR_CONDITIONAL_EVAL_ERROR,
|
||||||
new Integer(IProblem.PREPROCESSOR_CONDITIONAL_EVAL_ERROR),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.preproc.conditionalEval")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.preproc.conditionalEval")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.PREPROCESSOR_MACRO_USAGE_ERROR,
|
||||||
new Integer(IProblem.PREPROCESSOR_MACRO_USAGE_ERROR),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.preproc.macroUsage")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.preproc.macroUsage")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.PREPROCESSOR_CIRCULAR_INCLUSION,
|
||||||
new Integer(IProblem.PREPROCESSOR_CIRCULAR_INCLUSION),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.preproc.circularInclusion")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.preproc.circularInclusion")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.PREPROCESSOR_INVALID_DIRECTIVE,
|
||||||
new Integer(IProblem.PREPROCESSOR_INVALID_DIRECTIVE),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.preproc.invalidDirective")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.preproc.invalidDirective")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.PREPROCESSOR_MACRO_PASTING_ERROR,
|
||||||
new Integer(IProblem.PREPROCESSOR_MACRO_PASTING_ERROR),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.preproc.macroPasting")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.preproc.macroPasting")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.PREPROCESSOR_MISSING_RPAREN_PARMLIST,
|
||||||
new Integer(IProblem.PREPROCESSOR_MISSING_RPAREN_PARMLIST),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.preproc.missingRParen")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.preproc.missingRParen")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.PREPROCESSOR_INVALID_VA_ARGS,
|
||||||
new Integer(IProblem.PREPROCESSOR_INVALID_VA_ARGS),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.preproc.invalidVaArgs")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.preproc.invalidVaArgs")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SCANNER_INVALID_ESCAPECHAR,
|
||||||
new Integer(IProblem.SCANNER_INVALID_ESCAPECHAR),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.scanner.invalidEscapeChar")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.scanner.invalidEscapeChar")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SCANNER_UNBOUNDED_STRING,
|
||||||
new Integer(IProblem.SCANNER_UNBOUNDED_STRING),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.scanner.unboundedString")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.scanner.unboundedString")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SCANNER_BAD_FLOATING_POINT,
|
||||||
new Integer(IProblem.SCANNER_BAD_FLOATING_POINT),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.scanner.badFloatingPoint")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.scanner.badFloatingPoint")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SCANNER_BAD_HEX_FORMAT,
|
||||||
new Integer(IProblem.SCANNER_BAD_HEX_FORMAT),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.scanner.badHexFormat")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.scanner.badHexFormat")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SCANNER_BAD_OCTAL_FORMAT,
|
||||||
new Integer(IProblem.SCANNER_BAD_OCTAL_FORMAT),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.scanner.badOctalFormat")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.scanner.badOctalFormat")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SCANNER_BAD_DECIMAL_FORMAT,
|
||||||
new Integer(IProblem.SCANNER_BAD_DECIMAL_FORMAT),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.scanner.badDecimalFormat")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.scanner.badDecimalFormat")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SCANNER_ASSIGNMENT_NOT_ALLOWED,
|
||||||
new Integer(IProblem.SCANNER_ASSIGNMENT_NOT_ALLOWED),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.scanner.assignmentNotAllowed")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.scanner.assignmentNotAllowed")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SCANNER_DIVIDE_BY_ZERO,
|
||||||
new Integer(IProblem.SCANNER_DIVIDE_BY_ZERO),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.scanner.divideByZero")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.scanner.divideByZero")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SCANNER_MISSING_R_PAREN,
|
||||||
new Integer(IProblem.SCANNER_MISSING_R_PAREN),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.scanner.missingRParen")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.scanner.missingRParen")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SCANNER_EXPRESSION_SYNTAX_ERROR,
|
||||||
new Integer(IProblem.SCANNER_EXPRESSION_SYNTAX_ERROR),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.scanner.expressionSyntaxError")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.scanner.expressionSyntaxError")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SCANNER_ILLEGAL_IDENTIFIER,
|
||||||
new Integer(IProblem.SCANNER_ILLEGAL_IDENTIFIER),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.scanner.illegalIdentifier")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.scanner.illegalIdentifier")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SCANNER_BAD_CONDITIONAL_EXPRESSION,
|
||||||
new Integer(IProblem.SCANNER_BAD_CONDITIONAL_EXPRESSION),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.scanner.badConditionalExpression")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.scanner.badConditionalExpression")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SCANNER_UNEXPECTED_EOF,
|
||||||
new Integer(IProblem.SCANNER_UNEXPECTED_EOF),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.scanner.unexpectedEOF")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.scanner.unexpectedEOF")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SCANNER_BAD_CHARACTER,
|
||||||
new Integer(IProblem.SCANNER_BAD_CHARACTER),
|
|
||||||
ParserMessages.getString("ScannerProblemFactory.error.scanner.badCharacter")); //$NON-NLS-1$
|
ParserMessages.getString("ScannerProblemFactory.error.scanner.badCharacter")); //$NON-NLS-1$
|
||||||
errorMessages.put(
|
errorMessages.put(IProblem.SYNTAX_ERROR,
|
||||||
new Integer( IProblem.SYNTAX_ERROR ),
|
ParserMessages.getString("ParserProblemFactory.error.syntax.syntaxError")); //$NON-NLS-1$
|
||||||
ParserMessages.getString( "ParserProblemFactory.error.syntax.syntaxError")); //$NON-NLS-1$
|
|
||||||
}
|
}
|
||||||
protected final static String PROBLEM_PATTERN = "BaseProblemFactory.problemPattern"; //$NON-NLS-1$
|
protected final static String PROBLEM_PATTERN = "BaseProblemFactory.problemPattern"; //$NON-NLS-1$
|
||||||
|
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
if( message != null )
|
if (message != null)
|
||||||
return message;
|
return message;
|
||||||
|
|
||||||
String msg = (String) errorMessages.get( new Integer(id) );
|
String msg = errorMessages.get(id);
|
||||||
if (msg == null)
|
if (msg == null)
|
||||||
msg = ""; //$NON-NLS-1$
|
msg = ""; //$NON-NLS-1$
|
||||||
|
|
||||||
if (arg != null) {
|
if (arg != null) {
|
||||||
msg = MessageFormat.format(msg, arg);
|
msg = MessageFormat.format(msg, (Object[]) arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] args = null;
|
String[] args = null;
|
||||||
|
|
Loading…
Add table
Reference in a new issue