Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
小 白蛋
Intellij Community
Commits
c2d9d21a
Commit
c2d9d21a
authored
9 years ago
by
Gregory.Shrago
Browse files
Options
Download
Email Patches
Plain Diff
#143 back-port: some common stuff
parent
43a55b60
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
platform/core-api/src/com/intellij/psi/SyntaxTraverser.java
+27
-18
platform/core-api/src/com/intellij/psi/SyntaxTraverser.java
platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java
+49
-29
...src/com/intellij/lang/parser/GeneratedParserUtilBase.java
platform/util-rt/src/com/intellij/openapi/util/Conditions.java
+10
-13
...orm/util-rt/src/com/intellij/openapi/util/Conditions.java
platform/util-rt/src/com/intellij/util/Functions.java
+37
-2
platform/util-rt/src/com/intellij/util/Functions.java
platform/util/src/com/intellij/util/containers/FilteredTraverserBase.java
+4
-4
...c/com/intellij/util/containers/FilteredTraverserBase.java
platform/util/src/com/intellij/util/containers/JBIterable.java
+16
-0
...orm/util/src/com/intellij/util/containers/JBIterable.java
with
143 additions
and
66 deletions
+143
-66
platform/core-api/src/com/intellij/psi/SyntaxTraverser.java
+
27
-
18
View file @
c2d9d21a
...
...
@@ -7,6 +7,7 @@ import com.intellij.lang.PsiBuilder;
import
com.intellij.openapi.util.*
;
import
com.intellij.psi.tree.IElementType
;
import
com.intellij.psi.tree.IFileElementType
;
import
com.intellij.psi.util.PsiUtilCore
;
import
com.intellij.util.Function
;
import
com.intellij.util.containers.ContainerUtil
;
import
com.intellij.util.containers.FilteredTraverserBase
;
...
...
@@ -73,7 +74,7 @@ public class SyntaxTraverser<T> extends FilteredTraverserBase<T, SyntaxTraverser
@NotNull
public
static
SyntaxTraverser
<
LighterASTNode
>
lightTraverser
(
@NotNull
PsiBuilder
builder
)
{
LighterASTApi
api
=
new
LighterASTApi
(
builder
);
return
new
SyntaxTraverser
<
LighterASTNode
>(
api
,
Meta
.<
LighterASTNode
>
empty
().
withRoots
(
JBIterable
.
of
(
api
.
flyweigh
tStructure
.
getRoot
())));
return
new
SyntaxTraverser
<
LighterASTNode
>(
api
,
Meta
.<
LighterASTNode
>
empty
().
withRoots
(
JBIterable
.
of
(
api
.
ge
tStructure
()
.
getRoot
())));
}
public
final
Api
<
T
>
api
;
...
...
@@ -126,7 +127,7 @@ public class SyntaxTraverser<T> extends FilteredTraverserBase<T, SyntaxTraverser
@Nullable
public
T
getRawDeepestLast
()
{
for
(
T
result
=
getRoo
t
(),
last
;
result
!=
null
;
result
=
last
)
{
for
(
T
result
=
JBIterable
.
from
(
getRoots
()).
las
t
(),
last
;
result
!=
null
;
result
=
last
)
{
JBIterable
<
T
>
children
=
children
(
result
);
if
(
children
.
isEmpty
())
return
result
;
//noinspection AssignmentToForLoopParameter
...
...
@@ -295,7 +296,8 @@ public class SyntaxTraverser<T> extends FilteredTraverserBase<T, SyntaxTraverser
@NotNull
@Override
public
IElementType
typeOf
(
@NotNull
PsiElement
node
)
{
return
node
.
getNode
().
getElementType
();
IElementType
type
=
PsiUtilCore
.
getElementType
(
node
);
return
type
!=
null
?
type
:
IElementType
.
find
((
short
)
0
);
}
@NotNull
...
...
@@ -371,16 +373,14 @@ public class SyntaxTraverser<T> extends FilteredTraverserBase<T, SyntaxTraverser
}
private
abstract
static
class
FlyweightApi
<
T
>
extends
Api
<
T
>
{
final
FlyweightCapableTreeStructure
<
T
>
flyweightStructure
;
public
FlyweightApi
(
@NotNull
FlyweightCapableTreeStructure
<
T
>
structure
)
{
flyweightStructure
=
structure
;
}
@NotNull
abstract
FlyweightCapableTreeStructure
<
T
>
getStructure
();
@Nullable
@Override
public
T
parent
(
@NotNull
T
node
)
{
return
flyweigh
tStructure
.
getParent
(
node
);
return
ge
tStructure
()
.
getParent
(
node
);
}
@NotNull
...
...
@@ -389,26 +389,23 @@ public class SyntaxTraverser<T> extends FilteredTraverserBase<T, SyntaxTraverser
return
new
JBIterable
<
T
>()
{
@Override
public
Iterator
<
T
>
iterator
()
{
FlyweightCapableTreeStructure
<
T
>
structure
=
getStructure
();
Ref
<
T
[]>
ref
=
Ref
.
create
();
int
count
=
flyweightS
tructure
.
getChildren
(
flyweightS
tructure
.
prepareForGetChildren
(
node
),
ref
);
int
count
=
s
tructure
.
getChildren
(
s
tructure
.
prepareForGetChildren
(
node
),
ref
);
if
(
count
==
0
)
return
ContainerUtil
.
emptyIterator
();
T
[]
array
=
ref
.
get
();
LinkedList
<
T
>
list
=
ContainerUtil
.
newLinkedList
();
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
T
child
=
array
[
i
];
IElementType
childType
=
typeOf
(
child
);
// skip TokenType.* types, errors cannot be properly handled (no parents)
if
(
childType
==
TokenType
.
ERROR_ELEMENT
)
{
// todo remember error
continue
;
}
else
if
(
childType
==
TokenType
.
WHITE_SPACE
||
childType
==
TokenType
.
BAD_CHARACTER
)
{
// tokens and errors getParent() == null
if
(
childType
==
TokenType
.
WHITE_SPACE
||
childType
==
TokenType
.
BAD_CHARACTER
)
{
continue
;
}
array
[
i
]
=
null
;
// do not dispose meaningful TokenNodes
list
.
addLast
(
child
);
}
flyweightS
tructure
.
disposeChildren
(
array
,
count
);
s
tructure
.
disposeChildren
(
array
,
count
);
return
list
.
iterator
();
}
};
...
...
@@ -417,12 +414,24 @@ public class SyntaxTraverser<T> extends FilteredTraverserBase<T, SyntaxTraverser
private
static
class
LighterASTApi
extends
FlyweightApi
<
LighterASTNode
>
{
private
final
PsiBuilder
builder
;
private
final
ThreadLocalCachedValue
<
FlyweightCapableTreeStructure
<
LighterASTNode
>>
structure
=
new
ThreadLocalCachedValue
<
FlyweightCapableTreeStructure
<
LighterASTNode
>>()
{
@Override
protected
FlyweightCapableTreeStructure
<
LighterASTNode
>
create
()
{
return
builder
.
getLightTree
();
}
};
public
LighterASTApi
(
PsiBuilder
builder
)
{
super
(
builder
.
getLightTree
());
public
LighterASTApi
(
final
PsiBuilder
builder
)
{
this
.
builder
=
builder
;
}
@NotNull
@Override
FlyweightCapableTreeStructure
<
LighterASTNode
>
getStructure
()
{
return
structure
.
getValue
();
}
@NotNull
@Override
public
IElementType
typeOf
(
@NotNull
LighterASTNode
node
)
{
...
...
This diff is collapsed.
Click to expand it.
platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java
+
49
-
29
View file @
c2d9d21a
...
...
@@ -248,6 +248,14 @@ public class GeneratedParserUtilBase {
return
false
;
}
public
static
boolean
nextTokenIsSmart
(
PsiBuilder
builder
,
IElementType
token
)
{
return
nextTokenIsFast
(
builder
,
token
)
||
ErrorState
.
get
(
builder
).
completionState
!=
null
;
}
public
static
boolean
nextTokenIsSmart
(
PsiBuilder
builder
,
IElementType
...
tokens
)
{
return
nextTokenIsFast
(
builder
,
tokens
)
||
ErrorState
.
get
(
builder
).
completionState
!=
null
;
}
public
static
boolean
nextTokenIs
(
PsiBuilder
builder
,
String
frameName
,
IElementType
...
tokens
)
{
ErrorState
state
=
ErrorState
.
get
(
builder
);
if
(
state
.
completionState
!=
null
)
return
true
;
...
...
@@ -353,37 +361,9 @@ public class GeneratedParserUtilBase {
private
static
void
addCompletionVariant
(
@NotNull
PsiBuilder
builder
,
@NotNull
CompletionState
completionState
,
Object
o
)
{
int
offset
=
builder
.
getCurrentOffset
();
if
(!
builder
.
eof
()
&&
offset
==
builder
.
rawTokenTypeStart
(
1
))
return
;
// suppress for zero-length tokens
boolean
add
=
false
;
int
diff
=
completionState
.
offset
-
offset
;
String
text
=
completionState
.
convertItem
(
o
);
int
length
=
text
==
null
?
0
:
text
.
length
();
if
(
length
==
0
)
return
;
if
(
diff
==
0
)
{
add
=
true
;
}
else
if
(
diff
>
0
&&
diff
<=
length
)
{
CharSequence
fragment
=
builder
.
getOriginalText
().
subSequence
(
offset
,
completionState
.
offset
);
add
=
completionState
.
prefixMatches
(
fragment
.
toString
(),
text
);
}
else
if
(
diff
<
0
)
{
for
(
int
i
=-
1
;
;
i
--)
{
IElementType
type
=
builder
.
rawLookup
(
i
);
int
tokenStart
=
builder
.
rawTokenTypeStart
(
i
);
if
(
isWhitespaceOrComment
(
builder
,
type
))
{
diff
=
completionState
.
offset
-
tokenStart
;
}
else
if
(
type
!=
null
&&
tokenStart
<
completionState
.
offset
)
{
CharSequence
fragment
=
builder
.
getOriginalText
().
subSequence
(
tokenStart
,
completionState
.
offset
);
if
(
completionState
.
prefixMatches
(
fragment
.
toString
(),
text
))
{
diff
=
completionState
.
offset
-
tokenStart
;
}
break
;
}
else
break
;
}
add
=
diff
>=
0
&&
diff
<
length
;
}
boolean
add
=
length
!=
0
&&
completionState
.
prefixMatches
(
builder
,
text
);
add
=
add
&&
length
>
1
&&
!(
text
.
charAt
(
0
)
==
'<'
&&
text
.
charAt
(
length
-
1
)
==
'>'
)
&&
!(
text
.
charAt
(
0
)
==
'\''
&&
text
.
charAt
(
length
-
1
)
==
'\''
&&
length
<
5
);
if
(
add
)
{
...
...
@@ -689,6 +669,14 @@ public class GeneratedParserUtilBase {
}
}
public
static
boolean
withProtectedLastVariantPos
(
PsiBuilder
builder
,
int
level
,
Parser
parser
)
{
ErrorState
state
=
ErrorState
.
get
(
builder
);
int
backup
=
state
.
lastExpectedVariantPos
;
boolean
result
=
parser
.
parse
(
builder
,
level
);
state
.
lastExpectedVariantPos
=
backup
;
return
result
;
}
private
static
int
getLastVariantPos
(
ErrorState
state
,
int
defValue
)
{
return
state
.
lastExpectedVariantPos
<
0
?
defValue
:
state
.
lastExpectedVariantPos
;
}
...
...
@@ -759,6 +747,38 @@ public class GeneratedParserUtilBase {
items
.
add
(
text
);
}
public
boolean
prefixMatches
(
@NotNull
PsiBuilder
builder
,
@NotNull
String
text
)
{
int
builderOffset
=
builder
.
getCurrentOffset
();
int
diff
=
offset
-
builderOffset
;
int
length
=
text
.
length
();
if
(
diff
==
0
)
{
return
true
;
}
else
if
(
diff
>
0
&&
diff
<=
length
)
{
CharSequence
fragment
=
builder
.
getOriginalText
().
subSequence
(
builderOffset
,
offset
);
return
prefixMatches
(
fragment
.
toString
(),
text
);
}
else
if
(
diff
<
0
)
{
for
(
int
i
=-
1
;
;
i
--)
{
IElementType
type
=
builder
.
rawLookup
(
i
);
int
tokenStart
=
builder
.
rawTokenTypeStart
(
i
);
if
(
isWhitespaceOrComment
(
builder
,
type
))
{
diff
=
offset
-
tokenStart
;
}
else
if
(
type
!=
null
&&
tokenStart
<
offset
)
{
CharSequence
fragment
=
builder
.
getOriginalText
().
subSequence
(
tokenStart
,
offset
);
if
(
prefixMatches
(
fragment
.
toString
(),
text
))
{
diff
=
offset
-
tokenStart
;
}
break
;
}
else
break
;
}
return
diff
>=
0
&&
diff
<
length
;
}
return
false
;
}
public
boolean
prefixMatches
(
@NotNull
String
prefix
,
@NotNull
String
variant
)
{
boolean
matches
=
new
CamelHumpMatcher
(
prefix
,
false
).
prefixMatches
(
variant
.
replace
(
' '
,
'_'
));
if
(
matches
&&
StringUtil
.
isWhiteSpace
(
prefix
.
charAt
(
prefix
.
length
()
-
1
)))
{
...
...
This diff is collapsed.
Click to expand it.
platform/util-rt/src/com/intellij/openapi/util/Conditions.java
+
10
-
13
View file @
c2d9d21a
...
...
@@ -17,9 +17,10 @@
package
com.intellij.openapi.util
;
import
com.intellij.reference.SoftReference
;
import
com.intellij.util.ArrayUtilRt
;
import
com.intellij.util.Function
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.HashMap
;
/**
...
...
@@ -45,6 +46,10 @@ public class Conditions {
return
(
Condition
<
T
>)
Condition
.
NOT_NULL
;
}
public
static
<
T
>
Condition
<
T
>
constant
(
boolean
value
)
{
return
(
Condition
<
T
>)(
value
?
TRUE
:
FALSE
);
}
public
static
<
T
>
Condition
<
T
>
instanceOf
(
final
Class
<?>
clazz
)
{
return
new
Condition
<
T
>()
{
@Override
...
...
@@ -106,23 +111,15 @@ public class Conditions {
};
}
public
static
<
T
>
Condition
<
T
>
oneOf
(
final
T
...
options
)
{
return
new
Condition
<
T
>()
{
@Override
public
boolean
value
(
T
t
)
{
return
ArrayUtilRt
.
find
(
options
,
t
)
>=
0
;
}
};
public
static
<
T
>
Condition
<
T
>
oneOf
(
T
...
options
)
{
return
oneOf
(
Arrays
.
asList
(
options
));
}
public
static
<
T
>
Condition
<
T
>
oneOf
(
final
Iterable
<?
extends
T
>
options
)
{
public
static
<
T
>
Condition
<
T
>
oneOf
(
final
Collection
<?
extends
T
>
options
)
{
return
new
Condition
<
T
>()
{
@Override
public
boolean
value
(
T
t
)
{
for
(
T
option
:
options
)
{
if
(
Comparing
.
equal
(
option
,
t
))
return
true
;
}
return
false
;
return
options
.
contains
(
t
);
}
};
}
...
...
This diff is collapsed.
Click to expand it.
platform/util-rt/src/com/intellij/util/Functions.java
+
37
-
2
View file @
c2d9d21a
...
...
@@ -25,11 +25,37 @@ import java.util.Map;
*/
public
class
Functions
{
public
static
<
A
>
Function
.
Mono
<
A
>
id
()
{
return
(
Function
.
Mono
<
A
>)
Function
.
ID
;
}
public
static
<
A
,
B
>
Function
<
A
,
B
>
constant
(
final
B
b
)
{
return
new
Function
<
A
,
B
>()
{
@Override
public
B
fun
(
A
a
)
{
return
b
;
}
};
}
public
static
<
A
,
B
>
Function
<
A
,
B
>
identity
()
{
return
Function
.
ID
;
}
public
static
<
A
>
Function
<
A
,
String
>
toString
()
{
public
static
<
A
,
B
>
Function
<
A
,
B
>
cast
(
Class
<
B
>
clazz
)
{
return
Function
.
ID
;
}
public
static
<
A
,
B
,
C
>
Function
<
A
,
C
>
compose
(
final
Function
<
A
,
B
>
f1
,
final
Function
<
B
,
?
extends
C
>
f2
)
{
return
new
Function
<
A
,
C
>()
{
@Override
public
C
fun
(
A
a
)
{
return
f2
.
fun
(
f1
.
fun
(
a
));
}
};
}
public
static
<
A
>
Function
<
A
,
String
>
TO_STRING
()
{
return
Function
.
TO_STRING
;
}
...
...
@@ -49,7 +75,7 @@ public class Functions {
}
};
public
static
<
T
>
Function
<
T
,
Class
>
toClass
()
{
public
static
<
T
>
Function
<
T
,
Class
>
TO_CLASS
()
{
return
(
Function
<
T
,
Class
>)
TO_CLASS
;
}
...
...
@@ -74,4 +100,13 @@ public class Functions {
public
static
<
B
>
Function
<
Pair
<?,
B
>,
B
>
pairSecond
()
{
return
(
Function
<
Pair
<?,
B
>,
B
>)
PAIR_SECOND
;
}
public
static
Function
.
Mono
<
Integer
>
intIncrement
()
{
return
new
Function
.
Mono
<
Integer
>()
{
@Override
public
Integer
fun
(
Integer
integer
)
{
return
integer
+
1
;
}
};
}
}
This diff is collapsed.
Click to expand it.
platform/util/src/com/intellij/util/containers/FilteredTraverserBase.java
+
4
-
4
View file @
c2d9d21a
...
...
@@ -152,8 +152,8 @@ public abstract class FilteredTraverserBase<T, Self extends FilteredTraverserBas
}
@NotNull
public
JBIterable
<
T
>
children
(
@N
otN
ull
T
node
)
{
if
(
isAlwaysLeaf
(
node
))
{
public
JBIterable
<
T
>
children
(
@Null
able
T
node
)
{
if
(
node
==
null
||
isAlwaysLeaf
(
node
))
{
return
JBIterable
.
empty
();
}
else
if
(
meta
.
regard
.
next
==
null
&&
meta
.
forceDisregard
.
next
==
null
)
{
...
...
@@ -181,7 +181,7 @@ public abstract class FilteredTraverserBase<T, Self extends FilteredTraverserBas
public
abstract
static
class
EdgeFilter
<
T
>
extends
JBIterable
.
StatefulFilter
<
T
>
{
protected
T
curParent
;
protected
T
edgeSource
;
}
...
...
@@ -283,7 +283,7 @@ public abstract class FilteredTraverserBase<T, Self extends FilteredTraverserBas
if
(
impl
!=
(
invert
?
Condition
.
TRUE
:
Condition
.
FALSE
))
{
copy
=
new
Cond
<
Object
>(
invert
?
not
(
impl
)
:
impl
,
copy
);
if
(
impl
instanceof
EdgeFilter
)
{
((
EdgeFilter
)
impl
).
curParent
=
parent
;
((
EdgeFilter
)
impl
).
edgeSource
=
parent
;
}
}
if
(
c
.
next
==
null
)
{
...
...
This diff is collapsed.
Click to expand it.
platform/util/src/com/intellij/util/containers/JBIterable.java
+
16
-
0
View file @
c2d9d21a
...
...
@@ -202,6 +202,9 @@ public abstract class JBIterable<E> implements Iterable<E> {
* Returns the number of elements in this iterable.
*/
public
final
int
size
()
{
if
(
myIterable
instanceof
Collection
)
{
return
((
Collection
)
myIterable
).
size
();
}
int
count
=
0
;
for
(
E
ignored
:
myIterable
)
{
count
++;
...
...
@@ -223,6 +226,16 @@ public abstract class JBIterable<E> implements Iterable<E> {
return
false
;
}
/**
* Returns element at index if it is present; otherwise {@code null}
*/
public
final
E
get
(
int
index
)
{
if
(
myIterable
instanceof
List
)
{
return
index
>=
((
List
)
myIterable
).
size
()
?
null
:
((
List
<
E
>)
myIterable
).
get
(
index
);
}
return
skip
(
index
).
first
();
}
/**
* Returns a {@code JBIterable} whose iterators traverse first the elements of this iterable,
* followed by those of {@code other}. The iterators are not polled until necessary.
...
...
@@ -412,6 +425,9 @@ public abstract class JBIterable<E> implements Iterable<E> {
* Determines whether this iterable is empty.
*/
public
final
boolean
isEmpty
()
{
if
(
myIterable
instanceof
Collection
)
{
return
((
Collection
)
myIterable
).
isEmpty
();
}
return
!
myIterable
.
iterator
().
hasNext
();
}
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment