Moved commons and concourse editor to 'headless-services'
This commit is contained in:
@@ -0,0 +1,358 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.java.properties.antlr.parser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.antlr.v4.runtime.ANTLRErrorListener;
|
||||
import org.antlr.v4.runtime.ANTLRInputStream;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.ConsoleErrorListener;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.RecognitionException;
|
||||
import org.antlr.v4.runtime.Recognizer;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.atn.ATNConfigSet;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.springframework.ide.vscode.java.properties.antlr.parser.JavaPropertiesParser.CommentLineContext;
|
||||
import org.springframework.ide.vscode.java.properties.antlr.parser.JavaPropertiesParser.EmptyLineContext;
|
||||
import org.springframework.ide.vscode.java.properties.antlr.parser.JavaPropertiesParser.KeyContext;
|
||||
import org.springframework.ide.vscode.java.properties.antlr.parser.JavaPropertiesParser.PropertyLineContext;
|
||||
import org.springframework.ide.vscode.java.properties.antlr.parser.JavaPropertiesParser.SeparatorAndValueContext;
|
||||
import org.springframework.ide.vscode.java.properties.parser.ParseResults;
|
||||
import org.springframework.ide.vscode.java.properties.parser.Parser;
|
||||
import org.springframework.ide.vscode.java.properties.parser.Problem;
|
||||
import org.springframework.ide.vscode.java.properties.parser.ProblemCodes;
|
||||
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst;
|
||||
import org.springframework.ide.vscode.java.properties.parser.PropertiesFileEscapes;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* ANTLR based parser implementation
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class AntlrParser implements Parser {
|
||||
|
||||
@Override
|
||||
public ParseResults parse(String text) {
|
||||
ArrayList<Problem> syntaxErrors = new ArrayList<>();
|
||||
ArrayList<Problem> problems = new ArrayList<>();
|
||||
ArrayList<PropertiesAst.Node> astNodes = new ArrayList<>();
|
||||
|
||||
JavaPropertiesLexer lexer = new JavaPropertiesLexer(new ANTLRInputStream(text.toCharArray(), text.length()));
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
JavaPropertiesParser parser = new JavaPropertiesParser(tokens);
|
||||
|
||||
// To avoid printing parse errors in the console
|
||||
parser.removeErrorListener(ConsoleErrorListener.INSTANCE);
|
||||
|
||||
// Add listener to collect various parser errors
|
||||
parser.addErrorListener(new ANTLRErrorListener() {
|
||||
|
||||
@Override
|
||||
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line,
|
||||
int charPositionInLine, String msg, RecognitionException e) {
|
||||
syntaxErrors.add(createProblem(msg, ProblemCodes.PROPERTIES_SYNTAX_ERROR, (Token) offendingSymbol));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportAmbiguity(org.antlr.v4.runtime.Parser recognizer, DFA dfa, int startIndex, int stopIndex,
|
||||
boolean exact, BitSet ambigAlts, ATNConfigSet configs) {
|
||||
problems.add(createProblem("Ambiguity detected!", ProblemCodes.PROPERTIES_AMBIGUITY_ERROR, recognizer.getCurrentToken()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportAttemptingFullContext(org.antlr.v4.runtime.Parser recognizer, DFA dfa, int startIndex,
|
||||
int stopIndex, BitSet conflictingAlts, ATNConfigSet configs) {
|
||||
problems.add(createProblem("Full-Context attempt detected!", ProblemCodes.PROPERTIES_FULL_CONTEXT_ERROR, recognizer.getCurrentToken()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportContextSensitivity(org.antlr.v4.runtime.Parser recognizer, DFA dfa, int startIndex,
|
||||
int stopIndex, int prediction, ATNConfigSet configs) {
|
||||
problems.add(createProblem("Context sensitivity detected!", ProblemCodes.PROPERTIES_CONTEXT_SENSITIVITY_ERROR, recognizer.getCurrentToken()));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Add listener to the parse tree to collect AST nodes
|
||||
parser.addParseListener(new JavaPropertiesBaseListener() {
|
||||
|
||||
private Key key = null;
|
||||
private Value value = null;
|
||||
|
||||
@Override
|
||||
public void exitPropertyLine(PropertyLineContext ctx) {
|
||||
KeyValuePair pair = new KeyValuePair(ctx, key, value);
|
||||
key.parent = value.parent = pair;
|
||||
astNodes.add(pair);
|
||||
key = null;
|
||||
value = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitCommentLine(CommentLineContext ctx) {
|
||||
astNodes.add(new Comment(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitKey(KeyContext ctx) {
|
||||
key = new Key(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitSeparatorAndValue(SeparatorAndValueContext ctx) {
|
||||
value = new Value(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitEmptyLine(EmptyLineContext ctx) {
|
||||
astNodes.add(new EmptyLine(ctx));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
parser.parse();
|
||||
|
||||
// Collect and return parse results
|
||||
return new ParseResults(new PropertiesAst(ImmutableList.copyOf(astNodes)), ImmutableList.copyOf(syntaxErrors), ImmutableList.copyOf(problems));
|
||||
}
|
||||
|
||||
private static Problem createProblem(String message, String code, Token token) {
|
||||
return new Problem() {
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOffset() {
|
||||
if (token.getStartIndex() >= token.getStopIndex()) {
|
||||
// No range? Make error span the whole line then
|
||||
return token.getStartIndex() - token.getCharPositionInLine();
|
||||
} else {
|
||||
return token.getStartIndex();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
if (token.getStartIndex() >= token.getStopIndex()) {
|
||||
// No range? Make error span the whole line then
|
||||
return token.getCharPositionInLine();
|
||||
} else {
|
||||
return token.getStopIndex() - token.getStartIndex();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private static abstract class Node implements PropertiesAst.Node {
|
||||
|
||||
Node parent;
|
||||
List<Node> children;
|
||||
|
||||
abstract protected ParserRuleContext getContext();
|
||||
|
||||
@Override
|
||||
public int getOffset() {
|
||||
return getContext().getStart().getStartIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return getContext().getStop().getStartIndex() - getOffset() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Node> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class EmptyLine extends Node implements PropertiesAst.EmptyLine {
|
||||
|
||||
private EmptyLineContext context;
|
||||
|
||||
public EmptyLine(EmptyLineContext context) {
|
||||
super();
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EmptyLineContext getContext() {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Comment extends Node implements PropertiesAst.Comment {
|
||||
|
||||
private CommentLineContext context;
|
||||
|
||||
public Comment(CommentLineContext context) {
|
||||
super();
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOffset() {
|
||||
int i = 0;
|
||||
String text = context.getText();
|
||||
for (; i < context.getText().length() && Character.isWhitespace(text.charAt(i)); i++);
|
||||
return context.getStart().getStartIndex() + i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return context.getStop().getStartIndex() - getOffset() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommentLineContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class KeyValuePair extends Node implements PropertiesAst.KeyValuePair {
|
||||
|
||||
private PropertyLineContext context;
|
||||
private Key key;
|
||||
private Value value;
|
||||
|
||||
public KeyValuePair(PropertyLineContext context, Key key, Value value) {
|
||||
super();
|
||||
this.context = context;
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
this.children = ImmutableList.of(key, value);
|
||||
}
|
||||
|
||||
protected PropertyLineContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
// Exclude the line break at the end
|
||||
int length = super.getLength();
|
||||
String text = getContext().getText();
|
||||
if (text.charAt(getContext().getStop().getStartIndex() - getOffset()) == '\n') {
|
||||
length--;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class Key extends Node implements PropertiesAst.Key {
|
||||
|
||||
private KeyContext context;
|
||||
|
||||
public Key(KeyContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
protected KeyContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String decode() {
|
||||
// return context.getText().replace("\\:", ":").replace("\\=", "=");
|
||||
try {
|
||||
return PropertiesFileEscapes.unescape(context.getText());
|
||||
} catch (Exception e) {
|
||||
return context.getText().replace("\\:", ":").replace("\\=", "=");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyValuePair getParent() {
|
||||
return (KeyValuePair) super.getParent();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class Value extends Node implements PropertiesAst.Value {
|
||||
|
||||
private SeparatorAndValueContext context;
|
||||
private String value;
|
||||
private String decoded;
|
||||
|
||||
public Value(SeparatorAndValueContext context) {
|
||||
this.context = context;
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
// Remove the separator, if it exists
|
||||
value = context.getText().replaceAll("^\\s*[:=]?", "");
|
||||
// Remove all escaped line breaks with trailing spaces
|
||||
decoded = value.replaceAll("^\\s*", "").replaceAll("\\\\(\r?\n|\r)[ \t\f]*", "");
|
||||
try {
|
||||
decoded = PropertiesFileEscapes.unescape(decoded);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SeparatorAndValueContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String decode() {
|
||||
return decoded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOffset() {
|
||||
// Offset by 1 to skip the separator
|
||||
return context.getStart().getStartIndex() + (context.getText().length() - value.length());
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyValuePair getParent() {
|
||||
return (KeyValuePair) super.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
Backslash=1
|
||||
Colon=2
|
||||
Equals=3
|
||||
Exclamation=4
|
||||
Number=5
|
||||
LineBreak=6
|
||||
Space=7
|
||||
IdentifierChar=8
|
||||
'\\'=1
|
||||
':'=2
|
||||
'='=3
|
||||
'!'=4
|
||||
'#'=5
|
||||
@@ -0,0 +1,170 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016-2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
// Generated from JavaProperties.g4 by ANTLR 4.5.3
|
||||
package org.springframework.ide.vscode.java.properties.antlr.parser;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ErrorNode;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
/**
|
||||
* This class provides an empty implementation of {@link JavaPropertiesListener},
|
||||
* which can be extended to create a listener which only needs to handle a subset
|
||||
* of the available methods.
|
||||
*/
|
||||
public class JavaPropertiesBaseListener implements JavaPropertiesListener {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterParse(JavaPropertiesParser.ParseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitParse(JavaPropertiesParser.ParseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterLine(JavaPropertiesParser.LineContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitLine(JavaPropertiesParser.LineContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterPropertyLine(JavaPropertiesParser.PropertyLineContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitPropertyLine(JavaPropertiesParser.PropertyLineContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterCommentLine(JavaPropertiesParser.CommentLineContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitCommentLine(JavaPropertiesParser.CommentLineContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterEmptyLine(JavaPropertiesParser.EmptyLineContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitEmptyLine(JavaPropertiesParser.EmptyLineContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterKeyValuePair(JavaPropertiesParser.KeyValuePairContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitKeyValuePair(JavaPropertiesParser.KeyValuePairContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterKey(JavaPropertiesParser.KeyContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitKey(JavaPropertiesParser.KeyContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterKeyChar(JavaPropertiesParser.KeyCharContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitKeyChar(JavaPropertiesParser.KeyCharContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterSeparatorAndValue(JavaPropertiesParser.SeparatorAndValueContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitSeparatorAndValue(JavaPropertiesParser.SeparatorAndValueContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterValueChar(JavaPropertiesParser.ValueCharContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitValueChar(JavaPropertiesParser.ValueCharContext ctx) { }
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterEveryRule(ParserRuleContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitEveryRule(ParserRuleContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void visitTerminal(TerminalNode node) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void visitErrorNode(ErrorNode node) { }
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016-2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
// Generated from JavaProperties.g4 by ANTLR 4.5.3
|
||||
package org.springframework.ide.vscode.java.properties.antlr.parser;
|
||||
import org.antlr.v4.runtime.Lexer;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.TokenStream;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.misc.*;
|
||||
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||
public class JavaPropertiesLexer extends Lexer {
|
||||
static { RuntimeMetaData.checkVersion("4.5.3", RuntimeMetaData.VERSION); }
|
||||
|
||||
protected static final DFA[] _decisionToDFA;
|
||||
protected static final PredictionContextCache _sharedContextCache =
|
||||
new PredictionContextCache();
|
||||
public static final int
|
||||
Backslash=1, Colon=2, Equals=3, Exclamation=4, Number=5, LineBreak=6,
|
||||
Space=7, IdentifierChar=8;
|
||||
public static String[] modeNames = {
|
||||
"DEFAULT_MODE"
|
||||
};
|
||||
|
||||
public static final String[] ruleNames = {
|
||||
"Backslash", "Colon", "Equals", "Exclamation", "Number", "LineBreak",
|
||||
"Space", "IdentifierChar"
|
||||
};
|
||||
|
||||
private static final String[] _LITERAL_NAMES = {
|
||||
null, "'\\'", "':'", "'='", "'!'", "'#'"
|
||||
};
|
||||
private static final String[] _SYMBOLIC_NAMES = {
|
||||
null, "Backslash", "Colon", "Equals", "Exclamation", "Number", "LineBreak",
|
||||
"Space", "IdentifierChar"
|
||||
};
|
||||
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #VOCABULARY} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String[] tokenNames;
|
||||
static {
|
||||
tokenNames = new String[_SYMBOLIC_NAMES.length];
|
||||
for (int i = 0; i < tokenNames.length; i++) {
|
||||
tokenNames[i] = VOCABULARY.getLiteralName(i);
|
||||
if (tokenNames[i] == null) {
|
||||
tokenNames[i] = VOCABULARY.getSymbolicName(i);
|
||||
}
|
||||
|
||||
if (tokenNames[i] == null) {
|
||||
tokenNames[i] = "<INVALID>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String[] getTokenNames() {
|
||||
return tokenNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public Vocabulary getVocabulary() {
|
||||
return VOCABULARY;
|
||||
}
|
||||
|
||||
|
||||
public JavaPropertiesLexer(CharStream input) {
|
||||
super(input);
|
||||
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGrammarFileName() { return "JavaProperties.g4"; }
|
||||
|
||||
@Override
|
||||
public String[] getRuleNames() { return ruleNames; }
|
||||
|
||||
@Override
|
||||
public String getSerializedATN() { return _serializedATN; }
|
||||
|
||||
@Override
|
||||
public String[] getModeNames() { return modeNames; }
|
||||
|
||||
@Override
|
||||
public ATN getATN() { return _ATN; }
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2\n(\b\1\4\2\t\2\4"+
|
||||
"\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\3\2\3\2\3\3\3\3"+
|
||||
"\3\4\3\4\3\5\3\5\3\6\3\6\3\7\5\7\37\n\7\3\7\3\7\5\7#\n\7\3\b\3\b\3\t\3"+
|
||||
"\t\2\2\n\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\3\2\4\5\2\13\13\16\16\"\""+
|
||||
"\7\2\f\f\17\17\"\"<<??)\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2"+
|
||||
"\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\3\23\3\2\2\2\5\25"+
|
||||
"\3\2\2\2\7\27\3\2\2\2\t\31\3\2\2\2\13\33\3\2\2\2\r\"\3\2\2\2\17$\3\2\2"+
|
||||
"\2\21&\3\2\2\2\23\24\7^\2\2\24\4\3\2\2\2\25\26\7<\2\2\26\6\3\2\2\2\27"+
|
||||
"\30\7?\2\2\30\b\3\2\2\2\31\32\7#\2\2\32\n\3\2\2\2\33\34\7%\2\2\34\f\3"+
|
||||
"\2\2\2\35\37\7\17\2\2\36\35\3\2\2\2\36\37\3\2\2\2\37 \3\2\2\2 #\7\f\2"+
|
||||
"\2!#\7\17\2\2\"\36\3\2\2\2\"!\3\2\2\2#\16\3\2\2\2$%\t\2\2\2%\20\3\2\2"+
|
||||
"\2&\'\n\3\2\2\'\22\3\2\2\2\5\2\36\"\2";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
|
||||
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
|
||||
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
Backslash=1
|
||||
Colon=2
|
||||
Equals=3
|
||||
Exclamation=4
|
||||
Number=5
|
||||
LineBreak=6
|
||||
Space=7
|
||||
IdentifierChar=8
|
||||
'\\'=1
|
||||
':'=2
|
||||
'='=3
|
||||
'!'=4
|
||||
'#'=5
|
||||
@@ -0,0 +1,121 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016-2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
// Generated from JavaProperties.g4 by ANTLR 4.5.3
|
||||
package org.springframework.ide.vscode.java.properties.antlr.parser;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeListener;
|
||||
|
||||
/**
|
||||
* This interface defines a complete listener for a parse tree produced by
|
||||
* {@link JavaPropertiesParser}.
|
||||
*/
|
||||
public interface JavaPropertiesListener extends ParseTreeListener {
|
||||
/**
|
||||
* Enter a parse tree produced by {@link JavaPropertiesParser#parse}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterParse(JavaPropertiesParser.ParseContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link JavaPropertiesParser#parse}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitParse(JavaPropertiesParser.ParseContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link JavaPropertiesParser#line}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterLine(JavaPropertiesParser.LineContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link JavaPropertiesParser#line}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitLine(JavaPropertiesParser.LineContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link JavaPropertiesParser#propertyLine}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterPropertyLine(JavaPropertiesParser.PropertyLineContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link JavaPropertiesParser#propertyLine}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitPropertyLine(JavaPropertiesParser.PropertyLineContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link JavaPropertiesParser#commentLine}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterCommentLine(JavaPropertiesParser.CommentLineContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link JavaPropertiesParser#commentLine}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitCommentLine(JavaPropertiesParser.CommentLineContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link JavaPropertiesParser#emptyLine}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterEmptyLine(JavaPropertiesParser.EmptyLineContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link JavaPropertiesParser#emptyLine}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitEmptyLine(JavaPropertiesParser.EmptyLineContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link JavaPropertiesParser#keyValuePair}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterKeyValuePair(JavaPropertiesParser.KeyValuePairContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link JavaPropertiesParser#keyValuePair}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitKeyValuePair(JavaPropertiesParser.KeyValuePairContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link JavaPropertiesParser#key}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterKey(JavaPropertiesParser.KeyContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link JavaPropertiesParser#key}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitKey(JavaPropertiesParser.KeyContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link JavaPropertiesParser#keyChar}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterKeyChar(JavaPropertiesParser.KeyCharContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link JavaPropertiesParser#keyChar}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitKeyChar(JavaPropertiesParser.KeyCharContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link JavaPropertiesParser#separatorAndValue}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterSeparatorAndValue(JavaPropertiesParser.SeparatorAndValueContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link JavaPropertiesParser#separatorAndValue}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitSeparatorAndValue(JavaPropertiesParser.SeparatorAndValueContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link JavaPropertiesParser#valueChar}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterValueChar(JavaPropertiesParser.ValueCharContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link JavaPropertiesParser#valueChar}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitValueChar(JavaPropertiesParser.ValueCharContext ctx);
|
||||
}
|
||||
@@ -0,0 +1,793 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016-2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
// Generated from JavaProperties.g4 by ANTLR 4.5.3
|
||||
package org.springframework.ide.vscode.java.properties.antlr.parser;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.misc.*;
|
||||
import org.antlr.v4.runtime.tree.*;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||
public class JavaPropertiesParser extends Parser {
|
||||
static { RuntimeMetaData.checkVersion("4.5.3", RuntimeMetaData.VERSION); }
|
||||
|
||||
protected static final DFA[] _decisionToDFA;
|
||||
protected static final PredictionContextCache _sharedContextCache =
|
||||
new PredictionContextCache();
|
||||
public static final int
|
||||
Backslash=1, Colon=2, Equals=3, Exclamation=4, Number=5, LineBreak=6,
|
||||
Space=7, IdentifierChar=8;
|
||||
public static final int
|
||||
RULE_parse = 0, RULE_line = 1, RULE_propertyLine = 2, RULE_commentLine = 3,
|
||||
RULE_emptyLine = 4, RULE_keyValuePair = 5, RULE_key = 6, RULE_keyChar = 7,
|
||||
RULE_separatorAndValue = 8, RULE_valueChar = 9;
|
||||
public static final String[] ruleNames = {
|
||||
"parse", "line", "propertyLine", "commentLine", "emptyLine", "keyValuePair",
|
||||
"key", "keyChar", "separatorAndValue", "valueChar"
|
||||
};
|
||||
|
||||
private static final String[] _LITERAL_NAMES = {
|
||||
null, "'\\'", "':'", "'='", "'!'", "'#'"
|
||||
};
|
||||
private static final String[] _SYMBOLIC_NAMES = {
|
||||
null, "Backslash", "Colon", "Equals", "Exclamation", "Number", "LineBreak",
|
||||
"Space", "IdentifierChar"
|
||||
};
|
||||
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #VOCABULARY} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String[] tokenNames;
|
||||
static {
|
||||
tokenNames = new String[_SYMBOLIC_NAMES.length];
|
||||
for (int i = 0; i < tokenNames.length; i++) {
|
||||
tokenNames[i] = VOCABULARY.getLiteralName(i);
|
||||
if (tokenNames[i] == null) {
|
||||
tokenNames[i] = VOCABULARY.getSymbolicName(i);
|
||||
}
|
||||
|
||||
if (tokenNames[i] == null) {
|
||||
tokenNames[i] = "<INVALID>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String[] getTokenNames() {
|
||||
return tokenNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public Vocabulary getVocabulary() {
|
||||
return VOCABULARY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGrammarFileName() { return "JavaProperties.g4"; }
|
||||
|
||||
@Override
|
||||
public String[] getRuleNames() { return ruleNames; }
|
||||
|
||||
@Override
|
||||
public String getSerializedATN() { return _serializedATN; }
|
||||
|
||||
@Override
|
||||
public ATN getATN() { return _ATN; }
|
||||
|
||||
public JavaPropertiesParser(TokenStream input) {
|
||||
super(input);
|
||||
_interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
|
||||
}
|
||||
public static class ParseContext extends ParserRuleContext {
|
||||
public TerminalNode EOF() { return getToken(JavaPropertiesParser.EOF, 0); }
|
||||
public List<LineContext> line() {
|
||||
return getRuleContexts(LineContext.class);
|
||||
}
|
||||
public LineContext line(int i) {
|
||||
return getRuleContext(LineContext.class,i);
|
||||
}
|
||||
public ParseContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_parse; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).enterParse(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).exitParse(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final ParseContext parse() throws RecognitionException {
|
||||
ParseContext _localctx = new ParseContext(_ctx, getState());
|
||||
enterRule(_localctx, 0, RULE_parse);
|
||||
int _la;
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(23);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << Backslash) | (1L << Exclamation) | (1L << Number) | (1L << LineBreak) | (1L << Space) | (1L << IdentifierChar))) != 0)) {
|
||||
{
|
||||
{
|
||||
setState(20);
|
||||
line();
|
||||
}
|
||||
}
|
||||
setState(25);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
}
|
||||
setState(26);
|
||||
match(EOF);
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class LineContext extends ParserRuleContext {
|
||||
public PropertyLineContext propertyLine() {
|
||||
return getRuleContext(PropertyLineContext.class,0);
|
||||
}
|
||||
public CommentLineContext commentLine() {
|
||||
return getRuleContext(CommentLineContext.class,0);
|
||||
}
|
||||
public EmptyLineContext emptyLine() {
|
||||
return getRuleContext(EmptyLineContext.class,0);
|
||||
}
|
||||
public LineContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_line; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).enterLine(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).exitLine(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final LineContext line() throws RecognitionException {
|
||||
LineContext _localctx = new LineContext(_ctx, getState());
|
||||
enterRule(_localctx, 2, RULE_line);
|
||||
try {
|
||||
setState(31);
|
||||
_errHandler.sync(this);
|
||||
switch ( getInterpreter().adaptivePredict(_input,1,_ctx) ) {
|
||||
case 1:
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(28);
|
||||
propertyLine();
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
enterOuterAlt(_localctx, 2);
|
||||
{
|
||||
setState(29);
|
||||
commentLine();
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
enterOuterAlt(_localctx, 3);
|
||||
{
|
||||
setState(30);
|
||||
emptyLine();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class PropertyLineContext extends ParserRuleContext {
|
||||
public KeyValuePairContext keyValuePair() {
|
||||
return getRuleContext(KeyValuePairContext.class,0);
|
||||
}
|
||||
public List<TerminalNode> Space() { return getTokens(JavaPropertiesParser.Space); }
|
||||
public TerminalNode Space(int i) {
|
||||
return getToken(JavaPropertiesParser.Space, i);
|
||||
}
|
||||
public PropertyLineContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_propertyLine; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).enterPropertyLine(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).exitPropertyLine(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final PropertyLineContext propertyLine() throws RecognitionException {
|
||||
PropertyLineContext _localctx = new PropertyLineContext(_ctx, getState());
|
||||
enterRule(_localctx, 4, RULE_propertyLine);
|
||||
int _la;
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(36);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
while (_la==Space) {
|
||||
{
|
||||
{
|
||||
setState(33);
|
||||
match(Space);
|
||||
}
|
||||
}
|
||||
setState(38);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
}
|
||||
setState(39);
|
||||
keyValuePair();
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class CommentLineContext extends ParserRuleContext {
|
||||
public TerminalNode Exclamation() { return getToken(JavaPropertiesParser.Exclamation, 0); }
|
||||
public TerminalNode Number() { return getToken(JavaPropertiesParser.Number, 0); }
|
||||
public List<TerminalNode> LineBreak() { return getTokens(JavaPropertiesParser.LineBreak); }
|
||||
public TerminalNode LineBreak(int i) {
|
||||
return getToken(JavaPropertiesParser.LineBreak, i);
|
||||
}
|
||||
public TerminalNode EOF() { return getToken(JavaPropertiesParser.EOF, 0); }
|
||||
public List<TerminalNode> Space() { return getTokens(JavaPropertiesParser.Space); }
|
||||
public TerminalNode Space(int i) {
|
||||
return getToken(JavaPropertiesParser.Space, i);
|
||||
}
|
||||
public CommentLineContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_commentLine; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).enterCommentLine(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).exitCommentLine(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final CommentLineContext commentLine() throws RecognitionException {
|
||||
CommentLineContext _localctx = new CommentLineContext(_ctx, getState());
|
||||
enterRule(_localctx, 6, RULE_commentLine);
|
||||
int _la;
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(44);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
while (_la==Space) {
|
||||
{
|
||||
{
|
||||
setState(41);
|
||||
match(Space);
|
||||
}
|
||||
}
|
||||
setState(46);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
}
|
||||
setState(47);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==Exclamation || _la==Number) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
} else {
|
||||
consume();
|
||||
}
|
||||
setState(51);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << Backslash) | (1L << Colon) | (1L << Equals) | (1L << Exclamation) | (1L << Number) | (1L << Space) | (1L << IdentifierChar))) != 0)) {
|
||||
{
|
||||
{
|
||||
setState(48);
|
||||
_la = _input.LA(1);
|
||||
if ( _la <= 0 || (_la==LineBreak) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
} else {
|
||||
consume();
|
||||
}
|
||||
}
|
||||
}
|
||||
setState(53);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
}
|
||||
setState(54);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==EOF || _la==LineBreak) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
} else {
|
||||
consume();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class EmptyLineContext extends ParserRuleContext {
|
||||
public TerminalNode LineBreak() { return getToken(JavaPropertiesParser.LineBreak, 0); }
|
||||
public List<TerminalNode> Space() { return getTokens(JavaPropertiesParser.Space); }
|
||||
public TerminalNode Space(int i) {
|
||||
return getToken(JavaPropertiesParser.Space, i);
|
||||
}
|
||||
public EmptyLineContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_emptyLine; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).enterEmptyLine(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).exitEmptyLine(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final EmptyLineContext emptyLine() throws RecognitionException {
|
||||
EmptyLineContext _localctx = new EmptyLineContext(_ctx, getState());
|
||||
enterRule(_localctx, 8, RULE_emptyLine);
|
||||
int _la;
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(59);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
while (_la==Space) {
|
||||
{
|
||||
{
|
||||
setState(56);
|
||||
match(Space);
|
||||
}
|
||||
}
|
||||
setState(61);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
}
|
||||
setState(62);
|
||||
match(LineBreak);
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class KeyValuePairContext extends ParserRuleContext {
|
||||
public KeyContext key() {
|
||||
return getRuleContext(KeyContext.class,0);
|
||||
}
|
||||
public SeparatorAndValueContext separatorAndValue() {
|
||||
return getRuleContext(SeparatorAndValueContext.class,0);
|
||||
}
|
||||
public TerminalNode LineBreak() { return getToken(JavaPropertiesParser.LineBreak, 0); }
|
||||
public TerminalNode EOF() { return getToken(JavaPropertiesParser.EOF, 0); }
|
||||
public KeyValuePairContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_keyValuePair; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).enterKeyValuePair(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).exitKeyValuePair(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final KeyValuePairContext keyValuePair() throws RecognitionException {
|
||||
KeyValuePairContext _localctx = new KeyValuePairContext(_ctx, getState());
|
||||
enterRule(_localctx, 10, RULE_keyValuePair);
|
||||
int _la;
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(64);
|
||||
key();
|
||||
setState(65);
|
||||
separatorAndValue();
|
||||
setState(66);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==EOF || _la==LineBreak) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
} else {
|
||||
consume();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class KeyContext extends ParserRuleContext {
|
||||
public List<KeyCharContext> keyChar() {
|
||||
return getRuleContexts(KeyCharContext.class);
|
||||
}
|
||||
public KeyCharContext keyChar(int i) {
|
||||
return getRuleContext(KeyCharContext.class,i);
|
||||
}
|
||||
public KeyContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_key; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).enterKey(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).exitKey(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final KeyContext key() throws RecognitionException {
|
||||
KeyContext _localctx = new KeyContext(_ctx, getState());
|
||||
enterRule(_localctx, 12, RULE_key);
|
||||
int _la;
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(69);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
do {
|
||||
{
|
||||
{
|
||||
setState(68);
|
||||
keyChar();
|
||||
}
|
||||
}
|
||||
setState(71);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
} while ( _la==Backslash || _la==IdentifierChar );
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class KeyCharContext extends ParserRuleContext {
|
||||
public TerminalNode IdentifierChar() { return getToken(JavaPropertiesParser.IdentifierChar, 0); }
|
||||
public TerminalNode Backslash() { return getToken(JavaPropertiesParser.Backslash, 0); }
|
||||
public TerminalNode Colon() { return getToken(JavaPropertiesParser.Colon, 0); }
|
||||
public TerminalNode Equals() { return getToken(JavaPropertiesParser.Equals, 0); }
|
||||
public KeyCharContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_keyChar; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).enterKeyChar(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).exitKeyChar(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final KeyCharContext keyChar() throws RecognitionException {
|
||||
KeyCharContext _localctx = new KeyCharContext(_ctx, getState());
|
||||
enterRule(_localctx, 14, RULE_keyChar);
|
||||
int _la;
|
||||
try {
|
||||
setState(76);
|
||||
switch (_input.LA(1)) {
|
||||
case IdentifierChar:
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(73);
|
||||
match(IdentifierChar);
|
||||
}
|
||||
break;
|
||||
case Backslash:
|
||||
enterOuterAlt(_localctx, 2);
|
||||
{
|
||||
setState(74);
|
||||
match(Backslash);
|
||||
setState(75);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==Colon || _la==Equals) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
} else {
|
||||
consume();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NoViableAltException(this);
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class SeparatorAndValueContext extends ParserRuleContext {
|
||||
public TerminalNode Space() { return getToken(JavaPropertiesParser.Space, 0); }
|
||||
public TerminalNode Colon() { return getToken(JavaPropertiesParser.Colon, 0); }
|
||||
public TerminalNode Equals() { return getToken(JavaPropertiesParser.Equals, 0); }
|
||||
public List<ValueCharContext> valueChar() {
|
||||
return getRuleContexts(ValueCharContext.class);
|
||||
}
|
||||
public ValueCharContext valueChar(int i) {
|
||||
return getRuleContext(ValueCharContext.class,i);
|
||||
}
|
||||
public SeparatorAndValueContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_separatorAndValue; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).enterSeparatorAndValue(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).exitSeparatorAndValue(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final SeparatorAndValueContext separatorAndValue() throws RecognitionException {
|
||||
SeparatorAndValueContext _localctx = new SeparatorAndValueContext(_ctx, getState());
|
||||
enterRule(_localctx, 16, RULE_separatorAndValue);
|
||||
int _la;
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(78);
|
||||
_la = _input.LA(1);
|
||||
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << Colon) | (1L << Equals) | (1L << Space))) != 0)) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
} else {
|
||||
consume();
|
||||
}
|
||||
setState(82);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << Backslash) | (1L << Colon) | (1L << Equals) | (1L << Exclamation) | (1L << Number) | (1L << Space) | (1L << IdentifierChar))) != 0)) {
|
||||
{
|
||||
{
|
||||
setState(79);
|
||||
valueChar();
|
||||
}
|
||||
}
|
||||
setState(84);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class ValueCharContext extends ParserRuleContext {
|
||||
public TerminalNode IdentifierChar() { return getToken(JavaPropertiesParser.IdentifierChar, 0); }
|
||||
public TerminalNode Exclamation() { return getToken(JavaPropertiesParser.Exclamation, 0); }
|
||||
public TerminalNode Number() { return getToken(JavaPropertiesParser.Number, 0); }
|
||||
public TerminalNode Space() { return getToken(JavaPropertiesParser.Space, 0); }
|
||||
public TerminalNode Backslash() { return getToken(JavaPropertiesParser.Backslash, 0); }
|
||||
public TerminalNode LineBreak() { return getToken(JavaPropertiesParser.LineBreak, 0); }
|
||||
public TerminalNode Equals() { return getToken(JavaPropertiesParser.Equals, 0); }
|
||||
public TerminalNode Colon() { return getToken(JavaPropertiesParser.Colon, 0); }
|
||||
public ValueCharContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_valueChar; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).enterValueChar(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof JavaPropertiesListener ) ((JavaPropertiesListener)listener).exitValueChar(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final ValueCharContext valueChar() throws RecognitionException {
|
||||
ValueCharContext _localctx = new ValueCharContext(_ctx, getState());
|
||||
enterRule(_localctx, 18, RULE_valueChar);
|
||||
try {
|
||||
setState(93);
|
||||
switch (_input.LA(1)) {
|
||||
case IdentifierChar:
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(85);
|
||||
match(IdentifierChar);
|
||||
}
|
||||
break;
|
||||
case Exclamation:
|
||||
enterOuterAlt(_localctx, 2);
|
||||
{
|
||||
setState(86);
|
||||
match(Exclamation);
|
||||
}
|
||||
break;
|
||||
case Number:
|
||||
enterOuterAlt(_localctx, 3);
|
||||
{
|
||||
setState(87);
|
||||
match(Number);
|
||||
}
|
||||
break;
|
||||
case Space:
|
||||
enterOuterAlt(_localctx, 4);
|
||||
{
|
||||
setState(88);
|
||||
match(Space);
|
||||
}
|
||||
break;
|
||||
case Backslash:
|
||||
enterOuterAlt(_localctx, 5);
|
||||
{
|
||||
setState(89);
|
||||
match(Backslash);
|
||||
setState(90);
|
||||
match(LineBreak);
|
||||
}
|
||||
break;
|
||||
case Equals:
|
||||
enterOuterAlt(_localctx, 6);
|
||||
{
|
||||
setState(91);
|
||||
match(Equals);
|
||||
}
|
||||
break;
|
||||
case Colon:
|
||||
enterOuterAlt(_localctx, 7);
|
||||
{
|
||||
setState(92);
|
||||
match(Colon);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NoViableAltException(this);
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3\nb\4\2\t\2\4\3\t"+
|
||||
"\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\3"+
|
||||
"\2\7\2\30\n\2\f\2\16\2\33\13\2\3\2\3\2\3\3\3\3\3\3\5\3\"\n\3\3\4\7\4%"+
|
||||
"\n\4\f\4\16\4(\13\4\3\4\3\4\3\5\7\5-\n\5\f\5\16\5\60\13\5\3\5\3\5\7\5"+
|
||||
"\64\n\5\f\5\16\5\67\13\5\3\5\3\5\3\6\7\6<\n\6\f\6\16\6?\13\6\3\6\3\6\3"+
|
||||
"\7\3\7\3\7\3\7\3\b\6\bH\n\b\r\b\16\bI\3\t\3\t\3\t\5\tO\n\t\3\n\3\n\7\n"+
|
||||
"S\n\n\f\n\16\nV\13\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\5\13`\n\13"+
|
||||
"\3\13\2\2\f\2\4\6\b\n\f\16\20\22\24\2\7\3\2\6\7\3\2\b\b\3\3\b\b\3\2\4"+
|
||||
"\5\4\2\4\5\t\tg\2\31\3\2\2\2\4!\3\2\2\2\6&\3\2\2\2\b.\3\2\2\2\n=\3\2\2"+
|
||||
"\2\fB\3\2\2\2\16G\3\2\2\2\20N\3\2\2\2\22P\3\2\2\2\24_\3\2\2\2\26\30\5"+
|
||||
"\4\3\2\27\26\3\2\2\2\30\33\3\2\2\2\31\27\3\2\2\2\31\32\3\2\2\2\32\34\3"+
|
||||
"\2\2\2\33\31\3\2\2\2\34\35\7\2\2\3\35\3\3\2\2\2\36\"\5\6\4\2\37\"\5\b"+
|
||||
"\5\2 \"\5\n\6\2!\36\3\2\2\2!\37\3\2\2\2! \3\2\2\2\"\5\3\2\2\2#%\7\t\2"+
|
||||
"\2$#\3\2\2\2%(\3\2\2\2&$\3\2\2\2&\'\3\2\2\2\')\3\2\2\2(&\3\2\2\2)*\5\f"+
|
||||
"\7\2*\7\3\2\2\2+-\7\t\2\2,+\3\2\2\2-\60\3\2\2\2.,\3\2\2\2./\3\2\2\2/\61"+
|
||||
"\3\2\2\2\60.\3\2\2\2\61\65\t\2\2\2\62\64\n\3\2\2\63\62\3\2\2\2\64\67\3"+
|
||||
"\2\2\2\65\63\3\2\2\2\65\66\3\2\2\2\668\3\2\2\2\67\65\3\2\2\289\t\4\2\2"+
|
||||
"9\t\3\2\2\2:<\7\t\2\2;:\3\2\2\2<?\3\2\2\2=;\3\2\2\2=>\3\2\2\2>@\3\2\2"+
|
||||
"\2?=\3\2\2\2@A\7\b\2\2A\13\3\2\2\2BC\5\16\b\2CD\5\22\n\2DE\t\4\2\2E\r"+
|
||||
"\3\2\2\2FH\5\20\t\2GF\3\2\2\2HI\3\2\2\2IG\3\2\2\2IJ\3\2\2\2J\17\3\2\2"+
|
||||
"\2KO\7\n\2\2LM\7\3\2\2MO\t\5\2\2NK\3\2\2\2NL\3\2\2\2O\21\3\2\2\2PT\t\6"+
|
||||
"\2\2QS\5\24\13\2RQ\3\2\2\2SV\3\2\2\2TR\3\2\2\2TU\3\2\2\2U\23\3\2\2\2V"+
|
||||
"T\3\2\2\2W`\7\n\2\2X`\7\6\2\2Y`\7\7\2\2Z`\7\t\2\2[\\\7\3\2\2\\`\7\b\2"+
|
||||
"\2]`\7\5\2\2^`\7\4\2\2_W\3\2\2\2_X\3\2\2\2_Y\3\2\2\2_Z\3\2\2\2_[\3\2\2"+
|
||||
"\2_]\3\2\2\2_^\3\2\2\2`\25\3\2\2\2\f\31!&.\65=INT_";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
|
||||
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
|
||||
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.java.properties.parser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Results of parsing a text as Java Properties
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public final class ParseResults {
|
||||
|
||||
/**
|
||||
* Resultant AST created based on parse tree
|
||||
*/
|
||||
final public PropertiesAst ast;
|
||||
|
||||
/**
|
||||
* Any syntax errors discovered by the parser
|
||||
*/
|
||||
final public List<Problem> syntaxErrors;
|
||||
|
||||
/**
|
||||
* Any non-syntax problems discovered during parsing i.e. possible grammar problems such as ambiguity etc.
|
||||
*/
|
||||
final public List<Problem> problems;
|
||||
|
||||
public ParseResults(PropertiesAst ast, List<Problem> syntaxErrors, List<Problem> problems) {
|
||||
this.ast = ast;
|
||||
this.syntaxErrors = syntaxErrors;
|
||||
this.problems = problems;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.java.properties.parser;
|
||||
|
||||
/**
|
||||
* Basic Parser interface
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public interface Parser {
|
||||
|
||||
/**
|
||||
* Parses passed in text based on Java Properties format
|
||||
*
|
||||
* @param text Text to parse
|
||||
* @return Results of the parsing. See {@link ParseResults}
|
||||
*/
|
||||
ParseResults parse(String text);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.java.properties.parser;
|
||||
|
||||
/**
|
||||
* Parsing problem interface
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public interface Problem {
|
||||
|
||||
/**
|
||||
* The parsing problem message
|
||||
* @return The message string
|
||||
*/
|
||||
String getMessage();
|
||||
|
||||
/**
|
||||
* Problem's code
|
||||
* @return The code
|
||||
*/
|
||||
String getCode();
|
||||
|
||||
/**
|
||||
* Problem's start index in the document
|
||||
* @return Start index relative to the document
|
||||
*/
|
||||
int getOffset();
|
||||
|
||||
/**
|
||||
* Problem's range in symbols
|
||||
* @return Number of characters
|
||||
*/
|
||||
int getLength();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.java.properties.parser;
|
||||
|
||||
/**
|
||||
* Parsing error codes
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class ProblemCodes {
|
||||
public static final String PROPERTIES_SYNTAX_ERROR = "PROPERTIES_SYNTAX_ERROR";
|
||||
public static final String PROPERTIES_AMBIGUITY_ERROR = "AMBIGUITY_ERROR";
|
||||
public static final String PROPERTIES_FULL_CONTEXT_ERROR = "FULL_CONTEXT_ERROR";
|
||||
public static final String PROPERTIES_CONTEXT_SENSITIVITY_ERROR = "CONTEXT_SENSITIVITY_ERROR";
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.java.properties.parser;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Very basic AST for Java Properties to keep comments and key value pairs
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public final class PropertiesAst {
|
||||
|
||||
private List<Node> nodes;
|
||||
|
||||
public PropertiesAst(List<Node> nodes) {
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all AST nodes
|
||||
* @return List of AST nodes sorted by line number
|
||||
*/
|
||||
public List<Node> getAllNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves AST nodes of specific type
|
||||
* @param clazz Type of AST nodes
|
||||
* @return List of AST nodes of specific type sorted by line number
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> List<T> getNodes(Class<T> clazz) {
|
||||
List<Node> l = nodes.stream().filter(line -> {
|
||||
return clazz.isAssignableFrom(line.getClass());
|
||||
}).collect(Collectors.toList());
|
||||
return (List<T>) l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find node in AST corresponding to offset position
|
||||
* @param offset Position in the text
|
||||
* @return AST node corresponding to the offset position
|
||||
*/
|
||||
public Node findNode(int offset) {
|
||||
return findNode(nodes, offset, 0, nodes.size() - 1);
|
||||
}
|
||||
|
||||
private Node findNode(List<? extends Node> nodes, int offset, int start, int end) {
|
||||
if (nodes == null) {
|
||||
return null;
|
||||
}
|
||||
if (start == end) {
|
||||
Node node = nodes.get(start);
|
||||
if (node.getOffset() <= offset && offset <= node.getOffset() + node.getLength()) {
|
||||
Node found = findChildNode(node, offset);
|
||||
return found == null ? node : found;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if (start < end ) {
|
||||
int pivotIndex = (start + end) / 2;
|
||||
Node node = nodes.get(pivotIndex);
|
||||
if (node.getOffset() > offset) {
|
||||
return findNode(nodes, offset, start, pivotIndex - 1);
|
||||
} else if (offset > node.getOffset() + node.getLength()) {
|
||||
return findNode(nodes, offset, pivotIndex + 1, end);
|
||||
} else {
|
||||
Node found = findChildNode(node, offset);
|
||||
return found == null ? node : found;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Node findChildNode(Node node, int offset) {
|
||||
if (node.getChildren() == null) {
|
||||
return null;
|
||||
} else {
|
||||
return findNode(node.getChildren(), offset, 0, node.getChildren().size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Java Properties AST node
|
||||
*/
|
||||
public interface Node {
|
||||
|
||||
/**
|
||||
* Offset index of a node in the document
|
||||
* @return Offset index
|
||||
*/
|
||||
int getOffset();
|
||||
|
||||
/**
|
||||
* Number of characters a node occupies in the document
|
||||
* @return Number of characters
|
||||
*/
|
||||
int getLength();
|
||||
|
||||
/**
|
||||
* Node's parent
|
||||
* @return parent node
|
||||
*/
|
||||
Node getParent();
|
||||
|
||||
/**
|
||||
* Node's children
|
||||
* @return children nodes
|
||||
*/
|
||||
List<? extends Node> getChildren();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* AST node for comment
|
||||
*/
|
||||
public interface Comment extends Node {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* AST node for empty line
|
||||
*/
|
||||
public interface EmptyLine extends Node {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* AST node for property key and property value pair
|
||||
*/
|
||||
public interface KeyValuePair extends Node {
|
||||
|
||||
/**
|
||||
* AST node for key
|
||||
* @return Node for key
|
||||
*/
|
||||
Key getKey();
|
||||
|
||||
/**
|
||||
* AST node for value
|
||||
* @return Node for value
|
||||
*/
|
||||
Value getValue();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* AST node for property key
|
||||
*/
|
||||
public interface Key extends Node {
|
||||
|
||||
/**
|
||||
* Decode possibly encoded property name
|
||||
* @return Decoded property name
|
||||
*/
|
||||
String decode();
|
||||
|
||||
KeyValuePair getParent();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* AST node for property value
|
||||
*/
|
||||
public interface Value extends Node {
|
||||
|
||||
/**
|
||||
* Decode possibly encoded property value
|
||||
* @return Decoded property value
|
||||
*/
|
||||
String decode();
|
||||
|
||||
KeyValuePair getParent();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016-2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.springframework.ide.vscode.java.properties.parser;
|
||||
|
||||
/**
|
||||
* Helper class to convert between Java chars and the escaped form that must be used in .properties
|
||||
* files.
|
||||
*
|
||||
* @since 3.7
|
||||
*/
|
||||
public class PropertiesFileEscapes {
|
||||
|
||||
private static final char[] HEX_DIGITS= { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
|
||||
private static char toHex(int halfByte) {
|
||||
return HEX_DIGITS[(halfByte & 0xF)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the decimal value of the Hex digit, or -1 if the digit is not a valid Hex digit.
|
||||
*
|
||||
* @param digit the Hex digit
|
||||
* @return the decimal value of digit, or -1 if digit is not a valid Hex digit.
|
||||
*/
|
||||
private static int getHexDigitValue(char digit) {
|
||||
switch (digit) {
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
return digit - '0';
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
return 10 + digit - 'a';
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'F':
|
||||
return 10 + digit - 'A';
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a Java char to the escaped form that must be used in .properties files.
|
||||
*
|
||||
* @param c the Java char
|
||||
* @return escaped string
|
||||
*/
|
||||
public static String escape(char c) {
|
||||
return escape(c, true, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert characters in a Java string to the escaped form that must be used in .properties
|
||||
* files.
|
||||
*
|
||||
* @param s the Java string
|
||||
* @param escapeWhitespaceChars if <code>true</code>, escape whitespace characters
|
||||
* @param escapeBackslash if <code>true</code>, escape backslash characters
|
||||
* @param escapeUnicodeChars if <code>true</code>, escape unicode characters
|
||||
* @return escaped string
|
||||
*/
|
||||
public static String escape(String s, boolean escapeWhitespaceChars, boolean escapeBackslash, boolean escapeUnicodeChars) {
|
||||
StringBuffer sb= new StringBuffer(s.length());
|
||||
int length= s.length();
|
||||
for (int i= 0; i < length; i++) {
|
||||
char c= s.charAt(i);
|
||||
sb.append(escape(c, escapeWhitespaceChars, escapeBackslash, escapeUnicodeChars));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a Java char to the escaped form that must be used in .properties files.
|
||||
*
|
||||
* @param c the Java char
|
||||
* @param escapeWhitespaceChars if <code>true</code>, escape whitespace characters
|
||||
* @param escapeBackslash if <code>true</code>, escape backslash characters
|
||||
* @param escapeUnicodeChars if <code>true</code>, escape unicode characters
|
||||
* @return escaped string
|
||||
*/
|
||||
public static String escape(char c, boolean escapeWhitespaceChars, boolean escapeBackslash, boolean escapeUnicodeChars) {
|
||||
switch (c) {
|
||||
case '\t':
|
||||
return escapeWhitespaceChars ? "\\t" : "\t"; //$NON-NLS-1$//$NON-NLS-2$
|
||||
case '\n':
|
||||
return escapeWhitespaceChars ? "\\n" : "\n"; //$NON-NLS-1$//$NON-NLS-2$
|
||||
case '\f':
|
||||
return escapeWhitespaceChars ? "\\f" : "\r"; //$NON-NLS-1$//$NON-NLS-2$
|
||||
case '\r':
|
||||
return escapeWhitespaceChars ? "\\r" : "\r"; //$NON-NLS-1$//$NON-NLS-2$
|
||||
case '\\':
|
||||
return escapeBackslash ? "\\\\" : "\\"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
default:
|
||||
if (escapeUnicodeChars && ((c < 0x0020) || (c > 0x007e && c <= 0x00a0) || (c > 0x00ff))) {
|
||||
//NBSP (0x00a0) is escaped to differentiate from normal space character
|
||||
return new StringBuffer()
|
||||
.append('\\')
|
||||
.append('u')
|
||||
.append(toHex((c >> 12) & 0xF))
|
||||
.append(toHex((c >> 8) & 0xF))
|
||||
.append(toHex((c >> 4) & 0xF))
|
||||
.append(toHex(c & 0xF)).toString();
|
||||
|
||||
} else
|
||||
return String.valueOf(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an escaped string to a string composed of Java characters.
|
||||
*
|
||||
* @param s the escaped string
|
||||
* @return string composed of Java characters
|
||||
* @throws CoreException if the escaped string has a malformed \\uxxx sequence
|
||||
*/
|
||||
public static String unescape(String s) throws Exception {
|
||||
boolean isValidEscapedString= true;
|
||||
if (s == null)
|
||||
return null;
|
||||
|
||||
char aChar;
|
||||
int len= s.length();
|
||||
StringBuffer outBuffer= new StringBuffer(len);
|
||||
|
||||
for (int x= 0; x < len;) {
|
||||
aChar= s.charAt(x++);
|
||||
if (aChar == '\\') {
|
||||
if (x > len - 1) {
|
||||
return outBuffer.toString(); // silently ignore the \
|
||||
}
|
||||
aChar= s.charAt(x++);
|
||||
if (aChar == 'u') {
|
||||
// Read the xxxx
|
||||
int value= 0;
|
||||
if (x > len - 4) {
|
||||
throw new Exception("Malformed encoding for properties file");
|
||||
}
|
||||
StringBuffer buf= new StringBuffer("\\u"); //$NON-NLS-1$
|
||||
int digit= 0;
|
||||
for (int i= 0; i < 4; i++) {
|
||||
aChar= s.charAt(x++);
|
||||
digit= getHexDigitValue(aChar);
|
||||
if (digit == -1) {
|
||||
isValidEscapedString= false;
|
||||
x--;
|
||||
break;
|
||||
}
|
||||
value= (value << 4) + digit;
|
||||
buf.append(aChar);
|
||||
}
|
||||
outBuffer.append(digit == -1 ? buf.toString() : String.valueOf((char)value));
|
||||
} else if (aChar == 't') {
|
||||
outBuffer.append('\t');
|
||||
} else if (aChar == 'n') {
|
||||
outBuffer.append('\n');
|
||||
} else if (aChar == 'f') {
|
||||
outBuffer.append('\f');
|
||||
} else if (aChar == 'r') {
|
||||
outBuffer.append('\r');
|
||||
} else {
|
||||
outBuffer.append(aChar); // silently ignore the \
|
||||
}
|
||||
} else
|
||||
outBuffer.append(aChar);
|
||||
}
|
||||
if (isValidEscapedString) {
|
||||
return outBuffer.toString();
|
||||
} else {
|
||||
throw new Exception("Malformed encoding for properties file");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unescape backslash characters in a string.
|
||||
*
|
||||
* @param s the escaped string
|
||||
* @return string with backslash characters unescaped
|
||||
*/
|
||||
public static String unescapeBackslashes(String s) {
|
||||
if (s == null)
|
||||
return null;
|
||||
|
||||
char c;
|
||||
int length= s.length();
|
||||
StringBuffer outBuffer= new StringBuffer(length);
|
||||
|
||||
for (int i= 0; i < length;) {
|
||||
c= s.charAt(i++);
|
||||
if (c == '\\') {
|
||||
c= s.charAt(i++);
|
||||
}
|
||||
outBuffer.append(c);
|
||||
}
|
||||
|
||||
return outBuffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the given text contains any invalid escape sequence.
|
||||
*
|
||||
* @param text the text
|
||||
* @return <code>true</code> if text contains an invalid escape sequence, <code>false</code>
|
||||
* otherwise
|
||||
*/
|
||||
public static boolean containsInvalidEscapeSequence(String text) {
|
||||
try {
|
||||
//check for invalid unicode escapes
|
||||
unescape(text);
|
||||
} catch (Exception e) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int length= text.length();
|
||||
for (int i= 0; i < length; i++) {
|
||||
char c= text.charAt(i);
|
||||
if (c == '\\') {
|
||||
if (i < length - 1) {
|
||||
char nextC= text.charAt(i + 1);
|
||||
switch (nextC) {
|
||||
case 't':
|
||||
case 'n':
|
||||
case 'f':
|
||||
case 'r':
|
||||
case 'u':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '=':
|
||||
case ':':
|
||||
break;
|
||||
case '\\':
|
||||
i++;
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the given text contains an unescaped backslash character.
|
||||
*
|
||||
* @param text the text
|
||||
* @return <code>true</code> if text contains an unescaped backslash character,
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public static boolean containsUnescapedBackslash(String text) {
|
||||
int length= text.length();
|
||||
for (int i= 0; i < length; i++) {
|
||||
char c= text.charAt(i);
|
||||
if (c == '\\') {
|
||||
if (i < length - 1) {
|
||||
char nextC= text.charAt(i + 1);
|
||||
switch (nextC) {
|
||||
case '\\':
|
||||
i++;
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the given text contains only escaped backslash characters and no unescaped backslash
|
||||
* character.
|
||||
*
|
||||
* @param text the text
|
||||
* @return <code>true</code> if text contains only escaped backslash characters,
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public static boolean containsEscapedBackslashes(String text) {
|
||||
boolean result= false;
|
||||
int length= text.length();
|
||||
for (int i= 0; i < length; i++) {
|
||||
char c= text.charAt(i);
|
||||
if (c == '\\') {
|
||||
if (i < length - 1) {
|
||||
char nextC= text.charAt(i + 1);
|
||||
switch (nextC) {
|
||||
case '\\':
|
||||
i++;
|
||||
result= true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.java.properties.parser.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.java.properties.antlr.parser.AntlrParser;
|
||||
import org.springframework.ide.vscode.java.properties.parser.ParseResults;
|
||||
import org.springframework.ide.vscode.java.properties.parser.Parser;
|
||||
import org.springframework.ide.vscode.java.properties.parser.Problem;
|
||||
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst.Comment;
|
||||
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst.KeyValuePair;
|
||||
|
||||
public class PropertiesAntlrParserTest {
|
||||
|
||||
Parser parser = new AntlrParser();
|
||||
|
||||
private void testCommentLine(String text, String expectedComment) {
|
||||
ParseResults results = parser.parse(text);
|
||||
assertTrue(results.syntaxErrors.isEmpty());
|
||||
assertTrue(results.problems.isEmpty());
|
||||
assertEquals(1, results.ast.getAllNodes().size());
|
||||
|
||||
List<Comment> commentLines = results.ast.getNodes(Comment.class);
|
||||
assertEquals(1, commentLines.size());
|
||||
|
||||
Comment comment = commentLines.get(0);
|
||||
assertEquals(expectedComment, text.substring(comment.getOffset(), comment.getOffset() + comment.getLength()));
|
||||
}
|
||||
|
||||
private void testPropertyLine(String text,
|
||||
String expectedKey, String expectedEncodedKey,
|
||||
String expectedValue, String expectedEncodedValue) {
|
||||
ParseResults results = parser.parse(text);
|
||||
assertTrue(results.syntaxErrors.isEmpty());
|
||||
assertTrue(results.problems.isEmpty());
|
||||
assertEquals(1, results.ast.getAllNodes().size());
|
||||
|
||||
List<KeyValuePair> propertyLines = results.ast.getNodes(KeyValuePair.class);
|
||||
assertEquals(1, propertyLines.size());
|
||||
|
||||
KeyValuePair line = propertyLines.get(0);
|
||||
|
||||
assertNotNull(line.getKey());
|
||||
assertNotNull(line.getValue());
|
||||
|
||||
assertEquals(expectedKey, line.getKey().decode());
|
||||
assertEquals(expectedValue, line.getValue().decode());
|
||||
assertEquals(expectedEncodedKey, text.substring(line.getKey().getOffset(), line.getKey().getOffset() + line.getKey().getLength()));
|
||||
assertEquals(expectedEncodedValue, text.substring(line.getValue().getOffset(), line.getValue().getOffset() + line.getValue().getLength()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExclamationComment() throws Exception {
|
||||
testCommentLine("! This is comment", "! This is comment");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExclamationCommentWithSpaces() throws Exception {
|
||||
testCommentLine(" ! This is comment = ", "! This is comment = ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSharpComment() throws Exception {
|
||||
testCommentLine("# This is comment", "# This is comment");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSharpCommentWithSpaces() throws Exception {
|
||||
testCommentLine(" # This is comment = ", "# This is comment = ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyWithEqualsSeparator() throws Exception {
|
||||
testPropertyLine("key=value", "key", "key", "value", "value");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyWithEqualsSeparatorAndSpaces() throws Exception {
|
||||
testPropertyLine("key \t = \t \tvalue", "key", "key", "value", " \t \tvalue");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyWithColonSeparator() throws Exception {
|
||||
testPropertyLine("key:value", "key", "key", "value", "value");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyWithColonSeparatorAndSpaces() throws Exception {
|
||||
testPropertyLine("key \t : \t \tvalue", "key", "key", "value", " \t \tvalue");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyWithSpaceSeparator() throws Exception {
|
||||
testPropertyLine("key value", "key", "key", "value", "value");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpacesSeparation() throws Exception {
|
||||
testPropertyLine("key \t value", "key", "key", "value", "value");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValueWithSpaces() throws Exception {
|
||||
testPropertyLine("key=value 1 and more staff \t that is all", "key", "key", "value 1 and more staff \t that is all", "value 1 and more staff \t that is all");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyWithLeadingSpaces() throws Exception {
|
||||
testPropertyLine(" key2:value 2", "key2", "key2", "value 2", "value 2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyWithLeadingAndTrailingSpaces() throws Exception {
|
||||
testPropertyLine(" key3 \t :value3", "key3", "key3", "value3", "value3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodedKeyAndValue() throws Exception {
|
||||
testPropertyLine("ke\\:\\=y4=v\\\na\\\nl\\\nu\\\ne \t 4", "ke:=y4", "ke\\:\\=y4", "value \t 4", "v\\\na\\\nl\\\nu\\\ne \t 4");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualsValue() throws Exception {
|
||||
testPropertyLine("key\\=5==", "key=5", "key\\=5", "=", "=");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualsValueSeparatedWithEqualsAndSpace() throws Exception {
|
||||
testPropertyLine("key7 = =", "key7", "key7", "=", " =");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValueWithTrailingSpaces() throws Exception {
|
||||
testPropertyLine("key = value 1 ", "key", "key", "value 1 ", " value 1 ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnodeCharKeyAndValue() throws Exception {
|
||||
testPropertyLine("k\u2b22ey\u2b28 = val\u2b24ue 1\u2b24 ", "k\u2b22ey\u2b28", "k\u2b22ey\u2b28", "val\u2b24ue 1\u2b24 ", " val\u2b24ue 1\u2b24 ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVariousCharsInValue() throws Exception {
|
||||
for (char c = '!'; c < '@'; c++) {
|
||||
testPropertyLine("key=va" + c + "lue", "key", "key", "va" + c + "lue", "va" + c + "lue");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSyntaxError() throws Exception {
|
||||
String text = "abrakadabra";
|
||||
ParseResults results = parser.parse(text);
|
||||
assertEquals(1, results.syntaxErrors.size());
|
||||
assertTrue(results.problems.isEmpty());
|
||||
// One property line recorded. With key and empty value
|
||||
assertEquals(1, results.ast.getAllNodes().size());
|
||||
|
||||
Problem syntaxError = results.syntaxErrors.get(0);
|
||||
assertEquals(0, syntaxError.getOffset());
|
||||
assertEquals(text.length(), syntaxError.getLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleSyntaxErrors() throws Exception {
|
||||
String text = "abrakadabra\nkey:value\nsdcsdc";
|
||||
ParseResults results = parser.parse(text);
|
||||
assertEquals(2, results.syntaxErrors.size());
|
||||
assertTrue(results.problems.isEmpty());
|
||||
// One property line recorded. With key and empty value
|
||||
assertEquals(3, results.ast.getAllNodes().size());
|
||||
List<KeyValuePair> lines = results.ast.getNodes(KeyValuePair.class);
|
||||
assertEquals(3, lines.size());
|
||||
|
||||
// Test valid part
|
||||
KeyValuePair validLine = lines.get(1);
|
||||
assertNotNull(validLine.getKey());
|
||||
assertNotNull(validLine.getValue());
|
||||
assertEquals("key", text.substring(validLine.getKey().getOffset(), validLine.getKey().getOffset() + validLine.getKey().getLength()));
|
||||
assertEquals("value", text.substring(validLine.getValue().getOffset(), validLine.getValue().getOffset() + validLine.getValue().getLength()));
|
||||
|
||||
// Test errors
|
||||
Problem syntaxError1 = results.syntaxErrors.get(0);
|
||||
assertEquals(0, syntaxError1.getOffset());
|
||||
assertEquals(11, syntaxError1.getLength());
|
||||
Problem syntaxError2 = results.syntaxErrors.get(1);
|
||||
assertEquals(22, syntaxError2.getOffset());
|
||||
assertEquals(6, syntaxError2.getLength());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016-2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.springframework.ide.vscode.java.properties.parser.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.java.properties.antlr.parser.AntlrParser;
|
||||
import org.springframework.ide.vscode.java.properties.parser.ParseResults;
|
||||
import org.springframework.ide.vscode.java.properties.parser.Parser;
|
||||
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst.Comment;
|
||||
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst.EmptyLine;
|
||||
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst.Key;
|
||||
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst.KeyValuePair;
|
||||
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst.Node;
|
||||
import org.springframework.ide.vscode.java.properties.parser.PropertiesAst.Value;
|
||||
|
||||
public class PropertiesAstTest {
|
||||
|
||||
Parser parser = new AntlrParser();
|
||||
|
||||
@Test
|
||||
public void testLines1() throws Exception {
|
||||
ParseResults results = parser.parse("# Comment\n\n \t \t \n\t\t\n");
|
||||
assertTrue(results.syntaxErrors.isEmpty());
|
||||
assertTrue(results.problems.isEmpty());
|
||||
assertEquals(4, results.ast.getAllNodes().size());
|
||||
assertEquals(1, results.ast.getNodes(Comment.class).size());
|
||||
assertEquals(3, results.ast.getNodes(EmptyLine.class).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLines2() throws Exception {
|
||||
ParseResults results = parser.parse("\n\n \t \t \n# Comment\n\t\t\n");
|
||||
assertTrue(results.syntaxErrors.isEmpty());
|
||||
assertTrue(results.problems.isEmpty());
|
||||
assertEquals(5, results.ast.getAllNodes().size());
|
||||
assertEquals(1, results.ast.getNodes(Comment.class).size());
|
||||
assertEquals(4, results.ast.getNodes(EmptyLine.class).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLines3() throws Exception {
|
||||
ParseResults results = parser.parse("# Comment\n\nkey = value 1 \n \t \t \n\t\t\n");
|
||||
assertTrue(results.syntaxErrors.isEmpty());
|
||||
assertTrue(results.problems.isEmpty());
|
||||
assertEquals(5, results.ast.getAllNodes().size());
|
||||
assertEquals(1, results.ast.getNodes(Comment.class).size());
|
||||
assertEquals(1, results.ast.getNodes(KeyValuePair.class).size());
|
||||
assertEquals(3, results.ast.getNodes(EmptyLine.class).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLines4() throws Exception {
|
||||
ParseResults results = parser.parse("# Comment-1\n\nkey = value 1 \n# Comment-2");
|
||||
assertEquals(4, results.ast.getAllNodes().size());
|
||||
assertEquals(2, results.ast.getNodes(Comment.class).size());
|
||||
assertEquals(1, results.ast.getNodes(KeyValuePair.class).size());
|
||||
assertEquals(1, results.ast.getNodes(EmptyLine.class).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLines5() throws Exception {
|
||||
ParseResults results = parser.parse("#comment\nliquibase.enabled=\n#comment");
|
||||
assertEquals(3, results.ast.getAllNodes().size());
|
||||
assertEquals(2, results.ast.getNodes(Comment.class).size());
|
||||
assertEquals(1, results.ast.getNodes(KeyValuePair.class).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void positionComment() throws Exception {
|
||||
ParseResults results = parser.parse("# Comment\n" + "key = value\n");
|
||||
|
||||
Node node = results.ast.findNode(7);
|
||||
assertTrue(node instanceof Comment);
|
||||
assertTrue(node.getOffset() <= 7 && 7 <= node.getOffset() + node.getLength());
|
||||
|
||||
node = results.ast.findNode(9);
|
||||
assertTrue(node instanceof Comment);
|
||||
assertTrue(node.getOffset() <= 9 && 9 <= node.getOffset() + node.getLength());
|
||||
|
||||
node = results.ast.findNode(0);
|
||||
assertTrue(node instanceof Comment);
|
||||
assertTrue(node.getOffset() <= 0 && 0 <= node.getOffset() + node.getLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void positionEmptyLine() throws Exception {
|
||||
ParseResults results = parser.parse("# Comment\n" + "key = value\n" + "\t\n");
|
||||
Node node = results.ast.findNode(23);
|
||||
assertTrue(node instanceof EmptyLine);
|
||||
assertTrue(node.getOffset() <= 23 && 23 <= node.getOffset() + node.getLength());
|
||||
|
||||
node = results.ast.findNode(24);
|
||||
assertTrue(node instanceof EmptyLine);
|
||||
assertTrue(node.getOffset() <= 24 && 24 <= node.getOffset() + node.getLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void positionKey() throws Exception {
|
||||
ParseResults results = parser.parse("# Comment\n" + "key = value\n" + "\t\n");
|
||||
Node node = results.ast.findNode(10);
|
||||
assertTrue(node instanceof Key);
|
||||
assertTrue(node.getOffset() <= 10 && 10 <= node.getOffset() + node.getLength());
|
||||
|
||||
node = results.ast.findNode(12);
|
||||
assertTrue(node instanceof Key);
|
||||
assertTrue(node.getOffset() <= 12 && 12 <= node.getOffset() + node.getLength());
|
||||
|
||||
node = results.ast.findNode(13);
|
||||
assertTrue(node instanceof Key);
|
||||
assertTrue(node.getOffset() <= 13 && 13 <= node.getOffset() + node.getLength());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void positionPair() throws Exception {
|
||||
ParseResults results = parser.parse("# Comment\n" + "key = value\n" + "\t\n");
|
||||
Node node = results.ast.findNode(15);
|
||||
assertTrue(node instanceof KeyValuePair);
|
||||
assertTrue(node.getOffset() <= 15 && 15 <= node.getOffset() + node.getLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void positionValue() throws Exception {
|
||||
ParseResults results = parser.parse("# Comment\n" + "key = value\n");
|
||||
Node node = results.ast.findNode(17);
|
||||
assertTrue(node instanceof Value);
|
||||
assertTrue(node.getOffset() <= 17 && 17 <= node.getOffset() + node.getLength());
|
||||
|
||||
node = results.ast.findNode(22);
|
||||
assertTrue(node instanceof Value);
|
||||
assertTrue(node.getOffset() <= 22 && 22 <= node.getOffset() + node.getLength());
|
||||
|
||||
node = results.ast.findNode(16);
|
||||
assertTrue(node instanceof Value);
|
||||
assertTrue(node.getOffset() <= 16 && 16 <= node.getOffset() + node.getLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void positionValueEofAtEnd() throws Exception {
|
||||
ParseResults results = parser.parse("# Comment\n" + "key = value");
|
||||
Node node = results.ast.findNode(22);
|
||||
assertTrue(node instanceof Value);
|
||||
assertTrue(node.getOffset() <= 22 && 22 <= node.getOffset() + node.getLength());
|
||||
|
||||
node = results.ast.findNode(16);
|
||||
assertTrue(node instanceof Value);
|
||||
assertTrue(node.getOffset() <= 16 && 16 <= node.getOffset() + node.getLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void positionEmptyValue() throws Exception {
|
||||
ParseResults results = parser.parse("# Comment\n" + "key =");
|
||||
Node node = results.ast.findNode(16);
|
||||
assertTrue(node instanceof Value);
|
||||
assertTrue(node.getOffset() <= 16 && 16 <= node.getOffset() + node.getLength());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user