mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.highlighter;
|
||||
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
|
||||
/**
|
||||
* Created by Max Medvedev on 10/22/13
|
||||
*/
|
||||
public class GroovyDollarSlashyStringLexer extends GroovyStringLexerBase {
|
||||
public GroovyDollarSlashyStringLexer() {
|
||||
super(GroovyTokenTypes.mDOLLAR_SLASH_REGEX_CONTENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean checkForSimpleValidEscape(int start) {
|
||||
return charAt(start) == '$' && start + 1 < getBufferEnd() && (charAt(start + 1) == '$' || charAt(start + 1) == '/');
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean checkForInvalidSimpleEscape(int start) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean checkForHexCodeStart(int start) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+8
-86
@@ -15,107 +15,29 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.highlighter;
|
||||
|
||||
import com.intellij.diagnostic.LogMessageEx;
|
||||
import com.intellij.lexer.LexerBase;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.StringEscapesTokenTypes;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GroovySlashyStringLexer extends LexerBase {
|
||||
private static final Logger LOG = Logger.getInstance(GroovySlashyStringLexer.class);
|
||||
|
||||
private CharSequence myBuffer;
|
||||
private int myStart;
|
||||
private int myBufferEnd;
|
||||
private IElementType myTokenType;
|
||||
private int myEnd;
|
||||
|
||||
public class GroovySlashyStringLexer extends GroovyStringLexerBase {
|
||||
|
||||
public GroovySlashyStringLexer() {
|
||||
super(GroovyTokenTypes.mREGEX_CONTENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
|
||||
if (buffer.length()<endOffset) {
|
||||
LogMessageEx.error(LOG, "buffer Length: " + buffer.length() + ", endOffset: " + endOffset, buffer.toString());
|
||||
}
|
||||
|
||||
myBuffer = buffer;
|
||||
myEnd = startOffset;
|
||||
myBufferEnd = endOffset;
|
||||
myTokenType = locateToken();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private IElementType locateToken() {
|
||||
if (myEnd >= myBufferEnd) return null;
|
||||
|
||||
myStart = myEnd;
|
||||
if (checkForSlashEscape(myStart)) {
|
||||
myEnd = myStart + 2;
|
||||
return StringEscapesTokenTypes.VALID_STRING_ESCAPE_TOKEN;
|
||||
}
|
||||
else if (checkForHexCodeStart(myStart)) {
|
||||
for (myEnd = myStart + 2; myEnd < myStart + 6; myEnd++) {
|
||||
if (myEnd >= myBufferEnd || !StringUtil.isHexDigit(myBuffer.charAt(myEnd))) {
|
||||
return StringEscapesTokenTypes.INVALID_UNICODE_ESCAPE_TOKEN;
|
||||
}
|
||||
}
|
||||
return StringEscapesTokenTypes.VALID_STRING_ESCAPE_TOKEN;
|
||||
}
|
||||
|
||||
while (myEnd < myBufferEnd && !checkForSlashEscape(myEnd) && !checkForHexCodeStart(myEnd)) myEnd++;
|
||||
return GroovyTokenTypes.mREGEX_CONTENT;
|
||||
}
|
||||
|
||||
private boolean checkForSlashEscape(int start) {
|
||||
return myBuffer.charAt(start) == '\\' && start + 1 < myBufferEnd && myBuffer.charAt(start + 1) == '/';
|
||||
}
|
||||
|
||||
private boolean checkForHexCodeStart(int start) {
|
||||
return myBuffer.charAt(start) == '\\' && start + 1 < myBufferEnd && myBuffer.charAt(start + 1) == 'u';
|
||||
protected boolean checkForSimpleValidEscape(int start) {
|
||||
return charAt(start) == '\\' && start + 1 < getBufferEnd() && charAt(start + 1) == '/';
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getState() {
|
||||
return 0;
|
||||
protected boolean checkForInvalidSimpleEscape(int start) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IElementType getTokenType() {
|
||||
return myTokenType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTokenStart() {
|
||||
return myStart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTokenEnd() {
|
||||
return myEnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void advance() {
|
||||
myTokenType = locateToken();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CharSequence getBufferSequence() {
|
||||
return myBuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBufferEnd() {
|
||||
return myBufferEnd;
|
||||
protected boolean checkForHexCodeStart(int start) {
|
||||
return charAt(start) == '\\' && start + 1 < getBufferEnd() && charAt(start + 1) == 'u';
|
||||
}
|
||||
}
|
||||
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.highlighter;
|
||||
|
||||
import com.intellij.diagnostic.LogMessageEx;
|
||||
import com.intellij.lexer.LexerBase;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.StringEscapesTokenTypes;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by Max Medvedev on 10/22/13
|
||||
*/
|
||||
public abstract class GroovyStringLexerBase extends LexerBase {
|
||||
private static final Logger LOG = Logger.getInstance(GroovyStringLexerBase.class);
|
||||
private final IElementType myContentElementType;
|
||||
|
||||
private CharSequence myBuffer;
|
||||
private int myBufferEnd;
|
||||
|
||||
private int myStart;
|
||||
private int myEnd;
|
||||
private IElementType myTokenType;
|
||||
|
||||
public GroovyStringLexerBase(IElementType contentElementType) {
|
||||
myContentElementType = contentElementType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
|
||||
if (buffer.length() < endOffset) {
|
||||
LogMessageEx.error(LOG, "buffer Length: " + buffer.length() + ", endOffset: " + endOffset, buffer.toString());
|
||||
}
|
||||
|
||||
myBuffer = buffer;
|
||||
myEnd = startOffset;
|
||||
myBufferEnd = endOffset;
|
||||
myTokenType = locateToken();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private IElementType locateToken() {
|
||||
if (myEnd >= myBufferEnd) return null;
|
||||
|
||||
myStart = myEnd;
|
||||
if (checkForSimpleValidEscape(myStart)) {
|
||||
myEnd = myStart + 2;
|
||||
return StringEscapesTokenTypes.VALID_STRING_ESCAPE_TOKEN;
|
||||
}
|
||||
else if (checkForHexCodeStart(myStart)) {
|
||||
for (myEnd = myStart + 2; myEnd < myStart + 6; myEnd++) {
|
||||
if (myEnd >= myBufferEnd || !StringUtil.isHexDigit(myBuffer.charAt(myEnd))) {
|
||||
return StringEscapesTokenTypes.INVALID_UNICODE_ESCAPE_TOKEN;
|
||||
}
|
||||
}
|
||||
return StringEscapesTokenTypes.VALID_STRING_ESCAPE_TOKEN;
|
||||
}
|
||||
else if (checkForInvalidSimpleEscape(myStart)) {
|
||||
myEnd = myStart + 2;
|
||||
return StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN;
|
||||
}
|
||||
|
||||
while (myEnd < myBufferEnd && !checkForSimpleValidEscape(myEnd) && !checkForHexCodeStart(myEnd)) myEnd++;
|
||||
|
||||
return myContentElementType;
|
||||
}
|
||||
|
||||
protected abstract boolean checkForSimpleValidEscape(int start);
|
||||
|
||||
protected abstract boolean checkForInvalidSimpleEscape(int start);
|
||||
|
||||
protected abstract boolean checkForHexCodeStart(int start);
|
||||
|
||||
@Override
|
||||
public int getState() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IElementType getTokenType() {
|
||||
return myTokenType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTokenStart() {
|
||||
return myStart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTokenEnd() {
|
||||
return myEnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void advance() {
|
||||
myTokenType = locateToken();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CharSequence getBufferSequence() {
|
||||
return myBuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBufferEnd() {
|
||||
return myBufferEnd;
|
||||
}
|
||||
|
||||
protected char charAt(int i) {
|
||||
return myBuffer.charAt(i);
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -131,8 +131,8 @@ public class GroovySyntaxHighlighter extends SyntaxHighlighterBase implements Gr
|
||||
new IElementType[]{GroovyTokenTypes.mGSTRING_LITERAL}, IElementType.EMPTY_ARRAY);
|
||||
registerSelfStoppingLayer(new StringLiteralLexer(StringLiteralLexer.NO_QUOTE_CHAR, GroovyTokenTypes.mGSTRING_CONTENT, true, "$"),
|
||||
new IElementType[]{GroovyTokenTypes.mGSTRING_CONTENT}, IElementType.EMPTY_ARRAY);
|
||||
registerSelfStoppingLayer(new GroovySlashyStringLexer(), new IElementType[]{GroovyTokenTypes.mREGEX_CONTENT},
|
||||
IElementType.EMPTY_ARRAY);
|
||||
registerSelfStoppingLayer(new GroovySlashyStringLexer(), new IElementType[]{GroovyTokenTypes.mREGEX_CONTENT}, IElementType.EMPTY_ARRAY);
|
||||
registerSelfStoppingLayer(new GroovyDollarSlashyStringLexer(), new IElementType[]{GroovyTokenTypes.mDOLLAR_SLASH_REGEX_CONTENT}, IElementType.EMPTY_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,11 +19,11 @@ import com.intellij.lexer.FlexLexer;
|
||||
import com.intellij.psi.TokenType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import java.util.*;
|
||||
import java.lang.reflect.Field;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
%%
|
||||
|
||||
%{@SuppressWarnings({"UnnecessaryFullyQualifiedName", "FieldCanBeLocal", "UnusedDeclaration", "UnusedAssignment", "AccessStaticViaInstance",
|
||||
"AssignmentToStaticFieldFromInstanceMethod", "MethodMayBeStatic", "CStyleArrayDeclaration", "UnnecessarySemicolon"}) %}
|
||||
%class _GroovyLexer
|
||||
%implements FlexLexer, GroovyTokenTypes, TokenType
|
||||
%unicode
|
||||
@@ -144,7 +144,7 @@ mREGEX_ESC = \\ "/"
|
||||
|
||||
mREGEX_CONTENT = ({mREGEX_ESC} | [^"/""$"])+
|
||||
|
||||
mDOLLAR_SLASH_REGEX_CONTENT = ([^\/\$] | \/[^\/\$] )+
|
||||
mDOLLAR_SLASH_REGEX_CONTENT = ([^\/\$] | \$\$ | \$\/ | \/[^\/\$] )+
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -8,12 +8,11 @@
|
||||
private static final int ZZ_UNKNOWN_ERROR = 0;
|
||||
private static final int ZZ_NO_MATCH = 1;
|
||||
private static final int ZZ_PUSHBACK_2BIG = 2;
|
||||
private static final char[] EMPTY_BUFFER = new char[0];
|
||||
private static final int YYEOF = -1;
|
||||
private static java.io.Reader zzReader = null; // Fake
|
||||
|
||||
/* error messages for the codes above */
|
||||
private static final String ZZ_ERROR_MSG[] = {
|
||||
private static final String[] ZZ_ERROR_MSG = {
|
||||
"Unkown internal scanner error",
|
||||
"Error: could not match input",
|
||||
"Error: pushback value was too large"
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -89,7 +89,7 @@ public class GrSyntheticTypeElement extends LightElement implements PsiTypeEleme
|
||||
@Override
|
||||
public PsiElement replace(@NotNull PsiElement newElement) throws IncorrectOperationException {
|
||||
if (newElement instanceof PsiTypeElement) {
|
||||
GrTypeElement groovyTypeElement = GroovyPsiElementFactory.getInstance(getProject()).createTypeElement(newElement.getText(), newElement);
|
||||
GrTypeElement groovyTypeElement = GroovyPsiElementFactory.getInstance(getProject()).createTypeElement(((PsiTypeElement)newElement).getType());
|
||||
return myElement.replace(groovyTypeElement);
|
||||
}
|
||||
else {
|
||||
|
||||
+3
@@ -98,6 +98,9 @@ public class GroovyOverrideImplementUtil {
|
||||
|
||||
for (PsiAnnotation annotation : original.getModifierList().getAnnotations()) {
|
||||
final GrModifierList modifierList = parameter.getModifierList();
|
||||
|
||||
String qname = annotation.getQualifiedName();
|
||||
|
||||
if (annotation instanceof GrAnnotation) {
|
||||
modifierList.add(annotation);
|
||||
}
|
||||
|
||||
+2
@@ -356,6 +356,8 @@ public class ExpressionsParsingTest extends GroovyParsingTestCase {
|
||||
|
||||
public void testregex$dollarSlashyTriple() throws Throwable { doTest(); }
|
||||
|
||||
public void testregex$dollarSlashyUltimate() { doTest() }
|
||||
|
||||
public void testrelational$eq1() throws Throwable { doTest(); }
|
||||
|
||||
public void testrelational$inst0() throws Throwable { doTest(); }
|
||||
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
def name = "Guillaume"
|
||||
def date = "April, 1st"
|
||||
|
||||
def dollarSlashy = $/
|
||||
Hello $name,
|
||||
today we're ${date}.
|
||||
|
||||
$ dollar sign
|
||||
$$ escaped dollar sign
|
||||
\ backslash
|
||||
/ forward slash
|
||||
$/ escaped forward slash
|
||||
$/$ escaped dollar slashy string delimiter
|
||||
/$
|
||||
|
||||
assert [
|
||||
'Guillaume',
|
||||
'April, 1st',
|
||||
'$ dollar sign',
|
||||
'$ escaped dollar sign',
|
||||
'\\ backslash',
|
||||
'/ forward slash',
|
||||
'$/ escaped forward slash',
|
||||
'/$ escaped dollar slashy string delimiter'
|
||||
|
||||
].each { dollarSlashy.contains(it) }
|
||||
-----
|
||||
Groovy script
|
||||
Variable definitions
|
||||
Modifiers
|
||||
PsiElement(def)('def')
|
||||
PsiWhiteSpace(' ')
|
||||
Variable
|
||||
PsiElement(identifier)('name')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(=)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
Literal
|
||||
PsiElement(Gstring)('"Guillaume"')
|
||||
PsiElement(new line)('\n')
|
||||
Variable definitions
|
||||
Modifiers
|
||||
PsiElement(def)('def')
|
||||
PsiWhiteSpace(' ')
|
||||
Variable
|
||||
PsiElement(identifier)('date')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(=)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
Literal
|
||||
PsiElement(Gstring)('"April, 1st"')
|
||||
PsiElement(new line)('\n\n')
|
||||
Variable definitions
|
||||
Modifiers
|
||||
PsiElement(def)('def')
|
||||
PsiWhiteSpace(' ')
|
||||
Variable
|
||||
PsiElement(identifier)('dollarSlashy')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(=)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
Compound regular expression
|
||||
PsiElement($/ regex begin)('$/')
|
||||
GrStringContentImpl(GString content element)
|
||||
PsiElement($/ regex content)('\n Hello ')
|
||||
GString injection
|
||||
PsiElement($)('$')
|
||||
Reference expression
|
||||
PsiElement(identifier)('name')
|
||||
GrStringContentImpl(GString content element)
|
||||
PsiElement($/ regex content)(',\n today we're ')
|
||||
GString injection
|
||||
PsiElement($)('$')
|
||||
Closable block
|
||||
PsiElement({)('{')
|
||||
Parameter list
|
||||
<empty list>
|
||||
Reference expression
|
||||
PsiElement(identifier)('date')
|
||||
PsiElement(})('}')
|
||||
GrStringContentImpl(GString content element)
|
||||
PsiElement($/ regex content)('.\n\n $ dollar sign\n $$ escaped dollar sign\n \ backslash\n / forward slash\n $/ escaped forward slash\n $/$ escaped dollar slashy string delimiter\n')
|
||||
PsiElement($/ regex end)('/$')
|
||||
PsiElement(new line)('\n\n')
|
||||
ASSERT statement
|
||||
PsiElement(assert)('assert')
|
||||
PsiWhiteSpace(' ')
|
||||
Method call
|
||||
Reference expression
|
||||
Generalized list
|
||||
PsiElement([)('[')
|
||||
PsiWhiteSpace('\n ')
|
||||
Literal
|
||||
PsiElement(string)(''Guillaume'')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
Literal
|
||||
PsiElement(string)(''April, 1st'')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
Literal
|
||||
PsiElement(string)(''$ dollar sign'')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
Literal
|
||||
PsiElement(string)(''$ escaped dollar sign'')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
Literal
|
||||
PsiElement(string)(''\\ backslash'')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n ')
|
||||
Literal
|
||||
PsiElement(string)(''/ forward slash'')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n')
|
||||
Literal
|
||||
PsiElement(string)(''$/ escaped forward slash'')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace('\n')
|
||||
Literal
|
||||
PsiElement(string)(''/$ escaped dollar slashy string delimiter'')
|
||||
PsiWhiteSpace('\n\n')
|
||||
PsiElement(])(']')
|
||||
PsiElement(.)('.')
|
||||
PsiElement(identifier)('each')
|
||||
PsiWhiteSpace(' ')
|
||||
Arguments
|
||||
<empty list>
|
||||
Closable block
|
||||
PsiElement({)('{')
|
||||
PsiWhiteSpace(' ')
|
||||
Parameter list
|
||||
<empty list>
|
||||
Method call
|
||||
Reference expression
|
||||
Reference expression
|
||||
PsiElement(identifier)('dollarSlashy')
|
||||
PsiElement(.)('.')
|
||||
PsiElement(identifier)('contains')
|
||||
Arguments
|
||||
PsiElement(()('(')
|
||||
Reference expression
|
||||
PsiElement(identifier)('it')
|
||||
PsiElement())(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(})('}')
|
||||
Reference in New Issue
Block a user