summaryrefslogtreecommitdiff
path: root/java/java-impl/src/com/intellij/spi
diff options
context:
space:
mode:
Diffstat (limited to 'java/java-impl/src/com/intellij/spi')
-rw-r--r--java/java-impl/src/com/intellij/spi/SPIAnnotator.java57
-rw-r--r--java/java-impl/src/com/intellij/spi/SPICommenter.java54
-rw-r--r--java/java-impl/src/com/intellij/spi/SPIFileType.java92
-rw-r--r--java/java-impl/src/com/intellij/spi/SPIFileTypeFactory.java30
-rw-r--r--java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java38
-rw-r--r--java/java-impl/src/com/intellij/spi/parsing/SPIElementType.java30
-rw-r--r--java/java-impl/src/com/intellij/spi/parsing/SPIElementTypes.java30
-rw-r--r--java/java-impl/src/com/intellij/spi/parsing/SPILexer.java26
-rw-r--r--java/java-impl/src/com/intellij/spi/parsing/SPIParserDefinition.java137
-rw-r--r--java/java-impl/src/com/intellij/spi/parsing/SPITokenType.java28
-rw-r--r--java/java-impl/src/com/intellij/spi/parsing/_SPILexer.flex67
-rw-r--r--java/java-impl/src/com/intellij/spi/parsing/_SPILexer.java603
-rw-r--r--java/java-impl/src/com/intellij/spi/psi/SPIFile.java97
-rw-r--r--java/java-impl/src/com/intellij/spi/psi/SPIProviderElement.java127
-rw-r--r--java/java-impl/src/com/intellij/spi/psi/SPIProvidersElementList.java37
15 files changed, 1453 insertions, 0 deletions
diff --git a/java/java-impl/src/com/intellij/spi/SPIAnnotator.java b/java/java-impl/src/com/intellij/spi/SPIAnnotator.java
new file mode 100644
index 000000000000..f834542854cb
--- /dev/null
+++ b/java/java-impl/src/com/intellij/spi/SPIAnnotator.java
@@ -0,0 +1,57 @@
+/*
+ * 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 com.intellij.spi;
+
+import com.intellij.lang.annotation.AnnotationHolder;
+import com.intellij.lang.annotation.Annotator;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.util.ClassUtil;
+import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.spi.psi.SPIProviderElement;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * User: anna
+ */
+public class SPIAnnotator implements Annotator{
+ @Override
+ public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
+ final VirtualFile file = PsiUtilCore.getVirtualFile(element);
+ if (file != null && file.getFileType() instanceof SPIFileType) {
+ final String serviceProviderName = file.getName();
+ final PsiClass psiClass =
+ ClassUtil.findPsiClass(element.getManager(), serviceProviderName, null, true, element.getContainingFile().getResolveScope());
+ if (element instanceof PsiFile) {
+ if (psiClass == null) {
+ holder.createErrorAnnotation(element, "No service provider \"" + serviceProviderName + "\' found").setFileLevelAnnotation(true);
+ }
+ } else if (element instanceof SPIProviderElement) {
+ final PsiElement resolve = ((SPIProviderElement)element).resolve();
+ if (resolve == null) {
+ holder.createErrorAnnotation(element, "Cannot resolve symbol " + element.getText());
+ } else if (resolve instanceof PsiClass && psiClass != null) {
+ if (!((PsiClass)resolve).isInheritor(psiClass, true)) {
+ holder.createErrorAnnotation(element, "Registered extension should implement " + serviceProviderName);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/java/java-impl/src/com/intellij/spi/SPICommenter.java b/java/java-impl/src/com/intellij/spi/SPICommenter.java
new file mode 100644
index 000000000000..0afd9cdd717b
--- /dev/null
+++ b/java/java-impl/src/com/intellij/spi/SPICommenter.java
@@ -0,0 +1,54 @@
+/*
+ * 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 com.intellij.spi;
+
+import com.intellij.lang.Commenter;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * User: anna
+ */
+public class SPICommenter implements Commenter {
+ @Nullable
+ @Override
+ public String getLineCommentPrefix() {
+ return "#";
+ }
+
+ @Nullable
+ @Override
+ public String getBlockCommentPrefix() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public String getBlockCommentSuffix() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public String getCommentedBlockCommentPrefix() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public String getCommentedBlockCommentSuffix() {
+ return null;
+ }
+}
diff --git a/java/java-impl/src/com/intellij/spi/SPIFileType.java b/java/java-impl/src/com/intellij/spi/SPIFileType.java
new file mode 100644
index 000000000000..0d4a3bd8e474
--- /dev/null
+++ b/java/java-impl/src/com/intellij/spi/SPIFileType.java
@@ -0,0 +1,92 @@
+/*
+ * 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 com.intellij.spi;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.lang.spi.SPILanguage;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.LanguageFileType;
+import com.intellij.openapi.fileTypes.ex.FileTypeIdentifiableByVirtualFile;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * User: anna
+ */
+public class SPIFileType extends LanguageFileType implements FileTypeIdentifiableByVirtualFile {
+ public static final SPIFileType INSTANCE = new SPIFileType();
+
+ private SPIFileType() {
+ super(SPILanguage.INSTANCE);
+ }
+
+ @Override
+ public boolean isMyFileType(VirtualFile file) {
+ VirtualFile parent = file.getParent();
+ if (parent != null && "services".equals(parent.getName())) {
+ final VirtualFile gParent = parent.getParent();
+ if (gParent != null && "META-INF".equals(gParent.getName())) {
+ final String fileName = file.getName();
+ for (Object condition : Extensions.getExtensions("com.intellij.vetoSPICondition")) {
+ if (((Condition<String>)condition).value(fileName)) return false;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return "SPI";
+ }
+
+ @NotNull
+ @Override
+ public String getDescription() {
+ return "Service Provider Interface";
+ }
+
+ @NotNull
+ @Override
+ public String getDefaultExtension() {
+ return "";
+ }
+
+ @Nullable
+ @Override
+ public Icon getIcon() {
+ return AllIcons.FileTypes.Text;
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return false;
+ }
+
+ @Nullable
+ @Override
+ public String getCharset(@NotNull VirtualFile file, byte[] content) {
+ return CharsetToolkit.UTF8;
+ }
+}
diff --git a/java/java-impl/src/com/intellij/spi/SPIFileTypeFactory.java b/java/java-impl/src/com/intellij/spi/SPIFileTypeFactory.java
new file mode 100644
index 000000000000..ae61295651b4
--- /dev/null
+++ b/java/java-impl/src/com/intellij/spi/SPIFileTypeFactory.java
@@ -0,0 +1,30 @@
+/*
+ * 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 com.intellij.spi;
+
+import com.intellij.openapi.fileTypes.FileTypeConsumer;
+import com.intellij.openapi.fileTypes.FileTypeFactory;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * User: anna
+ */
+public class SPIFileTypeFactory extends FileTypeFactory {
+ @Override
+ public void createFileTypes(@NotNull FileTypeConsumer consumer) {
+ consumer.consume(SPIFileType.INSTANCE);
+ }
+}
diff --git a/java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java b/java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java
new file mode 100644
index 000000000000..a4a01485313d
--- /dev/null
+++ b/java/java-impl/src/com/intellij/spi/SPIGotoSuperHandler.java
@@ -0,0 +1,38 @@
+/*
+ * 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 com.intellij.spi;
+
+import com.intellij.codeInsight.navigation.JavaGotoSuperHandler;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiNameIdentifierOwner;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.spi.psi.SPIProviderElement;
+
+/**
+ * User: anna
+ */
+public class SPIGotoSuperHandler extends JavaGotoSuperHandler {
+ @Override
+ protected PsiNameIdentifierOwner getElement(PsiFile file, int offset) {
+ final SPIProviderElement providerElement = PsiTreeUtil.getParentOfType(file.findElementAt(offset), SPIProviderElement.class);
+ if (providerElement != null) {
+ return (PsiClass)providerElement.resolve();
+ }
+
+ return null;
+ }
+}
diff --git a/java/java-impl/src/com/intellij/spi/parsing/SPIElementType.java b/java/java-impl/src/com/intellij/spi/parsing/SPIElementType.java
new file mode 100644
index 000000000000..9d5c9cb655f9
--- /dev/null
+++ b/java/java-impl/src/com/intellij/spi/parsing/SPIElementType.java
@@ -0,0 +1,30 @@
+/*
+ * 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 com.intellij.spi.parsing;
+
+import com.intellij.psi.tree.IElementType;
+import com.intellij.lang.spi.SPILanguage;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * User: anna
+ */
+public class SPIElementType extends IElementType {
+ public SPIElementType(@NotNull @NonNls String debugName) {
+ super(debugName, SPILanguage.INSTANCE);
+ }
+}
diff --git a/java/java-impl/src/com/intellij/spi/parsing/SPIElementTypes.java b/java/java-impl/src/com/intellij/spi/parsing/SPIElementTypes.java
new file mode 100644
index 000000000000..228a8459d14f
--- /dev/null
+++ b/java/java-impl/src/com/intellij/spi/parsing/SPIElementTypes.java
@@ -0,0 +1,30 @@
+/*
+ * 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 com.intellij.spi.parsing;
+
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.IFileElementType;
+import com.intellij.psi.tree.TokenSet;
+import com.intellij.lang.spi.SPILanguage;
+
+public interface SPIElementTypes {
+
+ IFileElementType FILE = new IFileElementType(SPILanguage.INSTANCE);
+ IElementType PROVIDER = new IElementType("PROVIDER", SPILanguage.INSTANCE);
+
+ IElementType PROVIDERS_LIST = new IElementType("ROVIDER_LIST", SPILanguage.INSTANCE);
+ TokenSet PROVIDERS = TokenSet.create(PROVIDER);
+}
diff --git a/java/java-impl/src/com/intellij/spi/parsing/SPILexer.java b/java/java-impl/src/com/intellij/spi/parsing/SPILexer.java
new file mode 100644
index 000000000000..6a698a9ea5a8
--- /dev/null
+++ b/java/java-impl/src/com/intellij/spi/parsing/SPILexer.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.intellij.spi.parsing;
+
+import com.intellij.lexer.FlexAdapter;
+
+
+public class SPILexer extends FlexAdapter {
+ public SPILexer() {
+ super(new _SPILexer());
+ }
+}
diff --git a/java/java-impl/src/com/intellij/spi/parsing/SPIParserDefinition.java b/java/java-impl/src/com/intellij/spi/parsing/SPIParserDefinition.java
new file mode 100644
index 000000000000..f32bd37a11d9
--- /dev/null
+++ b/java/java-impl/src/com/intellij/spi/parsing/SPIParserDefinition.java
@@ -0,0 +1,137 @@
+/*
+ * 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 com.intellij.spi.parsing;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.lang.ParserDefinition;
+import com.intellij.lang.PsiBuilder;
+import com.intellij.lang.PsiParser;
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.IFileElementType;
+import com.intellij.psi.tree.TokenSet;
+import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.spi.psi.SPIProviderElement;
+import com.intellij.spi.psi.SPIProvidersElementList;
+import com.intellij.spi.psi.SPIFile;
+import com.intellij.lang.spi.SPILanguage;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * User: anna
+ */
+public class SPIParserDefinition implements ParserDefinition {
+ public static final IFileElementType SPI_FILE_ELEMENT_TYPE = new IFileElementType(SPILanguage.INSTANCE);
+
+ private static final TokenSet WHITE_SPACES = TokenSet.create(TokenType.WHITE_SPACE);
+ private static final Logger LOG = Logger.getInstance("#" + SPIParserDefinition.class.getName());
+
+ @NotNull
+ @Override
+ public Lexer createLexer(Project project) {
+ return new SPILexer();
+ }
+
+ @Override
+ public PsiParser createParser(Project project) {
+ return new PsiParser() {
+ @NotNull
+ @Override
+ public ASTNode parse(IElementType root, PsiBuilder builder) {
+ final PsiBuilder.Marker rootMarker = builder.mark();
+ final PsiBuilder.Marker propertiesList = builder.mark();
+ while (!builder.eof()) {
+ parseProvider(builder);
+ }
+ propertiesList.done(SPIElementTypes.PROVIDERS_LIST);
+ rootMarker.done(root);
+ return builder.getTreeBuilt();
+ }
+ };
+ }
+
+ @Override
+ public IFileElementType getFileNodeType() {
+ return SPI_FILE_ELEMENT_TYPE;
+ }
+
+ @NotNull
+ @Override
+ public TokenSet getWhitespaceTokens() {
+ return WHITE_SPACES;
+ }
+
+ @NotNull
+ @Override
+ public TokenSet getCommentTokens() {
+ return TokenSet.create(JavaTokenType.END_OF_LINE_COMMENT);
+ }
+
+ @NotNull
+ @Override
+ public TokenSet getStringLiteralElements() {
+ return TokenSet.EMPTY;
+ }
+
+ @NotNull
+ @Override
+ public PsiElement createElement(ASTNode node) {
+ final IElementType elementType = node.getElementType();
+ if (elementType == SPIElementTypes.PROVIDERS_LIST) {
+ return new SPIProvidersElementList(node);
+ }
+ if (elementType == SPIElementTypes.PROVIDER) {
+ return new SPIProviderElement(node);
+ }
+ return PsiUtilCore.NULL_PSI_ELEMENT;
+ }
+
+ @Override
+ public PsiFile createFile(FileViewProvider viewProvider) {
+ return new SPIFile(viewProvider);
+ }
+
+ @Override
+ public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) {
+ return SpaceRequirements.MAY;
+ }
+
+ public static void parseProvider(PsiBuilder builder) {
+ if (builder.getTokenType() == JavaTokenType.IDENTIFIER) {
+ final PsiBuilder.Marker prop = builder.mark();
+
+ parseProviderChar(builder);
+ prop.done(SPIElementTypes.PROVIDER);
+ }
+ else {
+ builder.advanceLexer();
+ builder.error("Unexpected token");
+ }
+ }
+
+ private static void parseProviderChar(final PsiBuilder builder) {
+ LOG.assertTrue(builder.getTokenType() == JavaTokenType.IDENTIFIER);
+ builder.advanceLexer();
+ final IElementType tokenType = builder.getTokenType();
+ if (tokenType == JavaTokenType.DOT || tokenType == SPITokenType.DOLLAR) {
+ builder.advanceLexer();
+ parseProviderChar(builder);
+ }
+ }
+}
diff --git a/java/java-impl/src/com/intellij/spi/parsing/SPITokenType.java b/java/java-impl/src/com/intellij/spi/parsing/SPITokenType.java
new file mode 100644
index 000000000000..cd8b0e6d4e08
--- /dev/null
+++ b/java/java-impl/src/com/intellij/spi/parsing/SPITokenType.java
@@ -0,0 +1,28 @@
+/*
+ * 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 com.intellij.spi.parsing;
+
+import com.intellij.psi.JavaTokenType;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.tree.java.IKeywordElementType;
+
+/**
+ * User: anna
+ */
+public interface SPITokenType extends JavaTokenType {
+ IElementType SHARP = new IKeywordElementType("SHARP");
+ IElementType DOLLAR = new IKeywordElementType("DOLLAR");
+}
diff --git a/java/java-impl/src/com/intellij/spi/parsing/_SPILexer.flex b/java/java-impl/src/com/intellij/spi/parsing/_SPILexer.flex
new file mode 100644
index 000000000000..b49ef5dac14a
--- /dev/null
+++ b/java/java-impl/src/com/intellij/spi/parsing/_SPILexer.flex
@@ -0,0 +1,67 @@
+/*
+ * 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 com.intellij.spi.parsing;
+
+import com.intellij.psi.JavaTokenType;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.spi.parsing.SPITokenType;
+import com.intellij.lexer.FlexLexer;
+
+@SuppressWarnings({"ALL"})
+%%
+
+%{
+ public _SPILexer() {
+ this((java.io.Reader)null);
+ }
+
+ public void goTo(int offset) {
+ zzCurrentPos = zzMarkedPos = zzStartRead = offset;
+ zzPushbackPos = 0;
+ zzAtEOF = offset < zzEndRead;
+ }
+%}
+
+%unicode
+%class _SPILexer
+%implements FlexLexer
+%function advance
+%type IElementType
+%eof{ return;
+%eof}
+
+WHITE_SPACE_CHAR=[\ \n\r\t\f]
+
+IDENTIFIER=[:jletter:] [:jletterdigit:]*
+
+END_OF_LINE_COMMENT="#"[^\r\n]*
+
+DIGIT = [0-9]
+DIGIT_OR_UNDERSCORE = [_0-9]
+DIGITS = {DIGIT} | {DIGIT} {DIGIT_OR_UNDERSCORE}*
+
+%%
+
+<YYINITIAL> {WHITE_SPACE_CHAR}+ { return JavaTokenType.WHITE_SPACE; }
+
+<YYINITIAL> {END_OF_LINE_COMMENT} { return JavaTokenType.END_OF_LINE_COMMENT; }
+<YYINITIAL> {IDENTIFIER} { return JavaTokenType.IDENTIFIER; }
+
+<YYINITIAL> "." { return JavaTokenType.DOT; }
+
+<YYINITIAL> "$" { return SPITokenType.DOLLAR; }
+
+<YYINITIAL> . { return JavaTokenType.BAD_CHARACTER; }
diff --git a/java/java-impl/src/com/intellij/spi/parsing/_SPILexer.java b/java/java-impl/src/com/intellij/spi/parsing/_SPILexer.java
new file mode 100644
index 000000000000..f08e8b295d1e
--- /dev/null
+++ b/java/java-impl/src/com/intellij/spi/parsing/_SPILexer.java
@@ -0,0 +1,603 @@
+/* The following code was generated by JFlex 1.4.3 on 6/5/13 9:20 PM */
+
+/*
+ * 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 com.intellij.spi.parsing;
+
+import com.intellij.psi.JavaTokenType;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.spi.parsing.SPITokenType;
+import com.intellij.lexer.FlexLexer;
+
+@SuppressWarnings({"ALL"})
+
+/**
+ * This class is a scanner generated by
+ * <a href="http://www.jflex.de/">JFlex</a> 1.4.3
+ * on 6/5/13 9:20 PM from the specification file
+ * <tt>D:/Projects/IDEA.anna/tools/lexer/../../community/java/java-impl/src/com/intellij/spi/parsing/_SPILexer.flex</tt>
+ */
+class _SPILexer implements FlexLexer {
+ /** initial size of the lookahead buffer */
+ private static final int ZZ_BUFFERSIZE = 16384;
+
+ /** lexical states */
+ public static final int YYINITIAL = 0;
+
+ /**
+ * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l
+ * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l
+ * at the beginning of a line
+ * l is of the form l = 2*k, k a non negative integer
+ */
+ private static final int ZZ_LEXSTATE[] = {
+ 0, 0
+ };
+
+ /**
+ * Translates characters to character classes
+ */
+ private static final String ZZ_CMAP_PACKED =
+ "\11\3\1\1\1\5\1\0\1\1\1\5\16\3\4\0\1\1\2\0"+
+ "\1\4\1\2\11\0\1\6\1\0\12\3\7\0\32\2\4\0\1\2"+
+ "\1\0\32\2\4\0\41\3\2\0\4\2\4\0\1\2\2\0\1\3"+
+ "\7\0\1\2\4\0\1\2\5\0\27\2\1\0\37\2\1\0\u013f\2"+
+ "\31\0\162\2\4\0\14\2\16\0\5\2\11\0\1\2\21\0\130\3"+
+ "\5\0\23\3\12\0\1\2\13\0\1\2\1\0\3\2\1\0\1\2"+
+ "\1\0\24\2\1\0\54\2\1\0\46\2\1\0\5\2\4\0\202\2"+
+ "\1\0\4\3\3\0\105\2\1\0\46\2\2\0\2\2\6\0\20\2"+
+ "\41\0\46\2\2\0\1\2\7\0\47\2\11\0\21\3\1\0\27\3"+
+ "\1\0\3\3\1\0\1\3\1\0\2\3\1\0\1\3\13\0\33\2"+
+ "\5\0\3\2\15\0\4\3\14\0\6\3\13\0\32\2\5\0\13\2"+
+ "\16\3\7\0\12\3\4\0\2\2\1\3\143\2\1\0\1\2\10\3"+
+ "\1\0\6\3\2\2\2\3\1\0\4\3\2\2\12\3\3\2\2\0"+
+ "\1\2\17\0\1\3\1\2\1\3\36\2\33\3\2\0\3\2\60\0"+
+ "\46\2\13\3\1\2\u014f\0\3\3\66\2\2\0\1\3\1\2\20\3"+
+ "\2\0\1\2\4\3\3\0\12\2\2\3\2\0\12\3\21\0\3\3"+
+ "\1\0\10\2\2\0\2\2\2\0\26\2\1\0\7\2\1\0\1\2"+
+ "\3\0\4\2\2\0\1\3\1\2\7\3\2\0\2\3\2\0\3\3"+
+ "\11\0\1\3\4\0\2\2\1\0\3\2\2\3\2\0\12\3\4\2"+
+ "\15\0\3\3\1\0\6\2\4\0\2\2\2\0\26\2\1\0\7\2"+
+ "\1\0\2\2\1\0\2\2\1\0\2\2\2\0\1\3\1\0\5\3"+
+ "\4\0\2\3\2\0\3\3\13\0\4\2\1\0\1\2\7\0\14\3"+
+ "\3\2\14\0\3\3\1\0\11\2\1\0\3\2\1\0\26\2\1\0"+
+ "\7\2\1\0\2\2\1\0\5\2\2\0\1\3\1\2\10\3\1\0"+
+ "\3\3\1\0\3\3\2\0\1\2\17\0\2\2\2\3\2\0\12\3"+
+ "\1\0\1\2\17\0\3\3\1\0\10\2\2\0\2\2\2\0\26\2"+
+ "\1\0\7\2\1\0\2\2\1\0\5\2\2\0\1\3\1\2\6\3"+
+ "\3\0\2\3\2\0\3\3\10\0\2\3\4\0\2\2\1\0\3\2"+
+ "\4\0\12\3\1\0\1\2\20\0\1\3\1\2\1\0\6\2\3\0"+
+ "\3\2\1\0\4\2\3\0\2\2\1\0\1\2\1\0\2\2\3\0"+
+ "\2\2\3\0\3\2\3\0\10\2\1\0\3\2\4\0\5\3\3\0"+
+ "\3\3\1\0\4\3\11\0\1\3\17\0\11\3\11\0\1\2\7\0"+
+ "\3\3\1\0\10\2\1\0\3\2\1\0\27\2\1\0\12\2\1\0"+
+ "\5\2\4\0\7\3\1\0\3\3\1\0\4\3\7\0\2\3\11\0"+
+ "\2\2\4\0\12\3\22\0\2\3\1\0\10\2\1\0\3\2\1\0"+
+ "\27\2\1\0\12\2\1\0\5\2\2\0\1\3\1\2\7\3\1\0"+
+ "\3\3\1\0\4\3\7\0\2\3\7\0\1\2\1\0\2\2\4\0"+
+ "\12\3\22\0\2\3\1\0\10\2\1\0\3\2\1\0\27\2\1\0"+
+ "\20\2\4\0\6\3\2\0\3\3\1\0\4\3\11\0\1\3\10\0"+
+ "\2\2\4\0\12\3\22\0\2\3\1\0\22\2\3\0\30\2\1\0"+
+ "\11\2\1\0\1\2\2\0\7\2\3\0\1\3\4\0\6\3\1\0"+
+ "\1\3\1\0\10\3\22\0\2\3\15\0\60\2\1\3\2\2\7\3"+
+ "\4\0\10\2\10\3\1\0\12\3\47\0\2\2\1\0\1\2\2\0"+
+ "\2\2\1\0\1\2\2\0\1\2\6\0\4\2\1\0\7\2\1\0"+
+ "\3\2\1\0\1\2\1\0\1\2\2\0\2\2\1\0\4\2\1\3"+
+ "\2\2\6\3\1\0\2\3\1\2\2\0\5\2\1\0\1\2\1\0"+
+ "\6\3\2\0\12\3\2\0\2\2\42\0\1\2\27\0\2\3\6\0"+
+ "\12\3\13\0\1\3\1\0\1\3\1\0\1\3\4\0\2\3\10\2"+
+ "\1\0\42\2\6\0\24\3\1\0\2\3\4\2\4\0\10\3\1\0"+
+ "\44\3\11\0\1\3\71\0\42\2\1\0\5\2\1\0\2\2\1\0"+
+ "\7\3\3\0\4\3\6\0\12\3\6\0\6\2\4\3\106\0\46\2"+
+ "\12\0\51\2\7\0\132\2\5\0\104\2\5\0\122\2\6\0\7\2"+
+ "\1\0\77\2\1\0\1\2\1\0\4\2\2\0\7\2\1\0\1\2"+
+ "\1\0\4\2\2\0\47\2\1\0\1\2\1\0\4\2\2\0\37\2"+
+ "\1\0\1\2\1\0\4\2\2\0\7\2\1\0\1\2\1\0\4\2"+
+ "\2\0\7\2\1\0\7\2\1\0\27\2\1\0\37\2\1\0\1\2"+
+ "\1\0\4\2\2\0\7\2\1\0\47\2\1\0\23\2\16\0\11\3"+
+ "\56\0\125\2\14\0\u026c\2\2\0\10\2\12\0\32\2\5\0\113\2"+
+ "\3\0\3\2\17\0\15\2\1\0\4\2\3\3\13\0\22\2\3\3"+
+ "\13\0\22\2\2\3\14\0\15\2\1\0\3\2\1\0\2\3\14\0"+
+ "\64\2\40\3\3\0\1\2\3\0\2\2\1\3\2\0\12\3\41\0"+
+ "\3\3\2\0\12\3\6\0\130\2\10\0\51\2\1\3\126\0\35\2"+
+ "\3\0\14\3\4\0\14\3\12\0\12\3\36\2\2\0\5\2\u038b\0"+
+ "\154\2\224\0\234\2\4\0\132\2\6\0\26\2\2\0\6\2\2\0"+
+ "\46\2\2\0\6\2\2\0\10\2\1\0\1\2\1\0\1\2\1\0"+
+ "\1\2\1\0\37\2\2\0\65\2\1\0\7\2\1\0\1\2\3\0"+
+ "\3\2\1\0\7\2\3\0\4\2\2\0\6\2\4\0\15\2\5\0"+
+ "\3\2\1\0\7\2\17\0\4\3\32\0\5\3\20\0\2\2\23\0"+
+ "\1\2\13\0\4\3\6\0\6\3\1\0\1\2\15\0\1\2\40\0"+
+ "\22\2\36\0\15\3\4\0\1\3\3\0\6\3\27\0\1\2\4\0"+
+ "\1\2\2\0\12\2\1\0\1\2\3\0\5\2\6\0\1\2\1\0"+
+ "\1\2\1\0\1\2\1\0\4\2\1\0\3\2\1\0\7\2\3\0"+
+ "\3\2\5\0\5\2\26\0\44\2\u0e81\0\3\2\31\0\11\2\6\3"+
+ "\1\0\5\2\2\0\5\2\4\0\126\2\2\0\2\3\2\0\3\2"+
+ "\1\0\137\2\5\0\50\2\4\0\136\2\21\0\30\2\70\0\20\2"+
+ "\u0200\0\u19b6\2\112\0\u51a6\2\132\0\u048d\2\u0773\0\u2ba4\2\u215c\0\u012e\2"+
+ "\2\0\73\2\225\0\7\2\14\0\5\2\5\0\1\2\1\3\12\2"+
+ "\1\0\15\2\1\0\5\2\1\0\1\2\1\0\2\2\1\0\2\2"+
+ "\1\0\154\2\41\0\u016b\2\22\0\100\2\2\0\66\2\50\0\15\2"+
+ "\3\0\20\3\20\0\4\3\17\0\2\2\30\0\3\2\31\0\1\2"+
+ "\6\0\5\2\1\0\207\2\2\0\1\3\4\0\1\2\13\0\12\3"+
+ "\7\0\32\2\4\0\1\2\1\0\32\2\12\0\132\2\3\0\6\2"+
+ "\2\0\6\2\2\0\6\2\2\0\3\2\3\0\2\2\3\0\2\2"+
+ "\22\0\3\3\4\0";
+
+ /**
+ * Translates characters to character classes
+ */
+ private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED);
+
+ /**
+ * Translates DFA states to action switch labels.
+ */
+ private static final int [] ZZ_ACTION = zzUnpackAction();
+
+ private static final String ZZ_ACTION_PACKED_0 =
+ "\1\0\1\1\1\2\1\3\1\4\1\5";
+
+ private static int [] zzUnpackAction() {
+ int [] result = new int[6];
+ int offset = 0;
+ offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
+ return result;
+ }
+
+ private static int zzUnpackAction(String packed, int offset, int [] result) {
+ int i = 0; /* index in packed string */
+ int j = offset; /* index in unpacked array */
+ int l = packed.length();
+ while (i < l) {
+ int count = packed.charAt(i++);
+ int value = packed.charAt(i++);
+ do result[j++] = value; while (--count > 0);
+ }
+ return j;
+ }
+
+
+ /**
+ * Translates a state to a row index in the transition table
+ */
+ private static final int [] ZZ_ROWMAP = zzUnpackRowMap();
+
+ private static final String ZZ_ROWMAP_PACKED_0 =
+ "\0\0\0\7\0\16\0\25\0\34\0\7";
+
+ private static int [] zzUnpackRowMap() {
+ int [] result = new int[6];
+ int offset = 0;
+ offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
+ return result;
+ }
+
+ private static int zzUnpackRowMap(String packed, int offset, int [] result) {
+ int i = 0; /* index in packed string */
+ int j = offset; /* index in unpacked array */
+ int l = packed.length();
+ while (i < l) {
+ int high = packed.charAt(i++) << 16;
+ result[j++] = high | packed.charAt(i++);
+ }
+ return j;
+ }
+
+ /**
+ * The transition table of the DFA
+ */
+ private static final int [] ZZ_TRANS = zzUnpackTrans();
+
+ private static final String ZZ_TRANS_PACKED_0 =
+ "\1\2\1\3\1\4\1\2\1\5\1\3\1\6\10\0"+
+ "\1\3\3\0\1\3\3\0\2\4\3\0\5\5\1\0"+
+ "\1\5";
+
+ private static int [] zzUnpackTrans() {
+ int [] result = new int[35];
+ int offset = 0;
+ offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
+ return result;
+ }
+
+ private static int zzUnpackTrans(String packed, int offset, int [] result) {
+ int i = 0; /* index in packed string */
+ int j = offset; /* index in unpacked array */
+ int l = packed.length();
+ while (i < l) {
+ int count = packed.charAt(i++);
+ int value = packed.charAt(i++);
+ value--;
+ do result[j++] = value; while (--count > 0);
+ }
+ return j;
+ }
+
+
+ /* error codes */
+ 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[] = {
+ "Unkown internal scanner error",
+ "Error: could not match input",
+ "Error: pushback value was too large"
+ };
+
+ /**
+ * ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>
+ */
+ private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();
+
+ private static final String ZZ_ATTRIBUTE_PACKED_0 =
+ "\1\0\1\11\3\1\1\11";
+
+ private static int [] zzUnpackAttribute() {
+ int [] result = new int[6];
+ int offset = 0;
+ offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
+ return result;
+ }
+
+ private static int zzUnpackAttribute(String packed, int offset, int [] result) {
+ int i = 0; /* index in packed string */
+ int j = offset; /* index in unpacked array */
+ int l = packed.length();
+ while (i < l) {
+ int count = packed.charAt(i++);
+ int value = packed.charAt(i++);
+ do result[j++] = value; while (--count > 0);
+ }
+ return j;
+ }
+
+ /** the current state of the DFA */
+ private int zzState;
+
+ /** the current lexical state */
+ private int zzLexicalState = YYINITIAL;
+
+ /** this buffer contains the current text to be matched and is
+ the source of the yytext() string */
+ private CharSequence zzBuffer = "";
+
+ /** this buffer may contains the current text array to be matched when it is cheap to acquire it */
+ private char[] zzBufferArray;
+
+ /** the textposition at the last accepting state */
+ private int zzMarkedPos;
+
+ /** the textposition at the last state to be included in yytext */
+ private int zzPushbackPos;
+
+ /** the current text position in the buffer */
+ private int zzCurrentPos;
+
+ /** startRead marks the beginning of the yytext() string in the buffer */
+ private int zzStartRead;
+
+ /** endRead marks the last character in the buffer, that has been read
+ from input */
+ private int zzEndRead;
+
+ /**
+ * zzAtBOL == true <=> the scanner is currently at the beginning of a line
+ */
+ private boolean zzAtBOL = true;
+
+ /** zzAtEOF == true <=> the scanner is at the EOF */
+ private boolean zzAtEOF;
+
+ /** denotes if the user-EOF-code has already been executed */
+ private boolean zzEOFDone;
+
+ /* user code: */
+ public _SPILexer() {
+ this((java.io.Reader)null);
+ }
+
+ public void goTo(int offset) {
+ zzCurrentPos = zzMarkedPos = zzStartRead = offset;
+ zzPushbackPos = 0;
+ zzAtEOF = offset < zzEndRead;
+ }
+
+
+ _SPILexer(java.io.Reader in) {
+ this.zzReader = in;
+ }
+
+ /**
+ * Creates a new scanner.
+ * There is also java.io.Reader version of this constructor.
+ *
+ * @param in the java.io.Inputstream to read input from.
+ */
+ _SPILexer(java.io.InputStream in) {
+ this(new java.io.InputStreamReader(in));
+ }
+
+ /**
+ * Unpacks the compressed character translation table.
+ *
+ * @param packed the packed character translation table
+ * @return the unpacked character translation table
+ */
+ private static char [] zzUnpackCMap(String packed) {
+ char [] map = new char[0x10000];
+ int i = 0; /* index in packed string */
+ int j = 0; /* index in unpacked array */
+ while (i < 1666) {
+ int count = packed.charAt(i++);
+ char value = packed.charAt(i++);
+ do map[j++] = value; while (--count > 0);
+ }
+ return map;
+ }
+
+ public final int getTokenStart(){
+ return zzStartRead;
+ }
+
+ public final int getTokenEnd(){
+ return getTokenStart() + yylength();
+ }
+
+ public void reset(CharSequence buffer, int start, int end,int initialState){
+ zzBuffer = buffer;
+ zzBufferArray = com.intellij.util.text.CharArrayUtil.fromSequenceWithoutCopying(buffer);
+ zzCurrentPos = zzMarkedPos = zzStartRead = start;
+ zzPushbackPos = 0;
+ zzAtEOF = false;
+ zzAtBOL = true;
+ zzEndRead = end;
+ yybegin(initialState);
+ }
+
+ /**
+ * Refills the input buffer.
+ *
+ * @return <code>false</code>, iff there was new input.
+ *
+ * @exception java.io.IOException if any I/O-Error occurs
+ */
+ private boolean zzRefill() throws java.io.IOException {
+ return true;
+ }
+
+
+ /**
+ * Returns the current lexical state.
+ */
+ public final int yystate() {
+ return zzLexicalState;
+ }
+
+
+ /**
+ * Enters a new lexical state
+ *
+ * @param newState the new lexical state
+ */
+ public final void yybegin(int newState) {
+ zzLexicalState = newState;
+ }
+
+
+ /**
+ * Returns the text matched by the current regular expression.
+ */
+ public final CharSequence yytext() {
+ return zzBuffer.subSequence(zzStartRead, zzMarkedPos);
+ }
+
+
+ /**
+ * Returns the character at position <tt>pos</tt> from the
+ * matched text.
+ *
+ * It is equivalent to yytext().charAt(pos), but faster
+ *
+ * @param pos the position of the character to fetch.
+ * A value from 0 to yylength()-1.
+ *
+ * @return the character at position pos
+ */
+ public final char yycharat(int pos) {
+ return zzBufferArray != null ? zzBufferArray[zzStartRead+pos]:zzBuffer.charAt(zzStartRead+pos);
+ }
+
+
+ /**
+ * Returns the length of the matched text region.
+ */
+ public final int yylength() {
+ return zzMarkedPos-zzStartRead;
+ }
+
+
+ /**
+ * Reports an error that occured while scanning.
+ *
+ * In a wellformed scanner (no or only correct usage of
+ * yypushback(int) and a match-all fallback rule) this method
+ * will only be called with things that "Can't Possibly Happen".
+ * If this method is called, something is seriously wrong
+ * (e.g. a JFlex bug producing a faulty scanner etc.).
+ *
+ * Usual syntax/scanner level error handling should be done
+ * in error fallback rules.
+ *
+ * @param errorCode the code of the errormessage to display
+ */
+ private void zzScanError(int errorCode) {
+ String message;
+ try {
+ message = ZZ_ERROR_MSG[errorCode];
+ }
+ catch (ArrayIndexOutOfBoundsException e) {
+ message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR];
+ }
+
+ throw new Error(message);
+ }
+
+
+ /**
+ * Pushes the specified amount of characters back into the input stream.
+ *
+ * They will be read again by then next call of the scanning method
+ *
+ * @param number the number of characters to be read again.
+ * This number must not be greater than yylength()!
+ */
+ public void yypushback(int number) {
+ if ( number > yylength() )
+ zzScanError(ZZ_PUSHBACK_2BIG);
+
+ zzMarkedPos -= number;
+ }
+
+
+ /**
+ * Contains user EOF-code, which will be executed exactly once,
+ * when the end of file is reached
+ */
+ private void zzDoEOF() {
+ if (!zzEOFDone) {
+ zzEOFDone = true;
+
+ }
+ }
+
+
+ /**
+ * Resumes scanning until the next regular expression is matched,
+ * the end of input is encountered or an I/O-Error occurs.
+ *
+ * @return the next token
+ * @exception java.io.IOException if any I/O-Error occurs
+ */
+ public IElementType advance() throws java.io.IOException {
+ int zzInput;
+ int zzAction;
+
+ // cached fields:
+ int zzCurrentPosL;
+ int zzMarkedPosL;
+ int zzEndReadL = zzEndRead;
+ CharSequence zzBufferL = zzBuffer;
+ char[] zzBufferArrayL = zzBufferArray;
+ char [] zzCMapL = ZZ_CMAP;
+
+ int [] zzTransL = ZZ_TRANS;
+ int [] zzRowMapL = ZZ_ROWMAP;
+ int [] zzAttrL = ZZ_ATTRIBUTE;
+
+ while (true) {
+ zzMarkedPosL = zzMarkedPos;
+
+ zzAction = -1;
+
+ zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL;
+
+ zzState = ZZ_LEXSTATE[zzLexicalState];
+
+
+ zzForAction: {
+ while (true) {
+
+ if (zzCurrentPosL < zzEndReadL)
+ zzInput = (zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++] : zzBufferL.charAt(zzCurrentPosL++));
+ else if (zzAtEOF) {
+ zzInput = YYEOF;
+ break zzForAction;
+ }
+ else {
+ // store back cached positions
+ zzCurrentPos = zzCurrentPosL;
+ zzMarkedPos = zzMarkedPosL;
+ boolean eof = zzRefill();
+ // get translated positions and possibly new buffer
+ zzCurrentPosL = zzCurrentPos;
+ zzMarkedPosL = zzMarkedPos;
+ zzBufferL = zzBuffer;
+ zzEndReadL = zzEndRead;
+ if (eof) {
+ zzInput = YYEOF;
+ break zzForAction;
+ }
+ else {
+ zzInput = (zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++] : zzBufferL.charAt(zzCurrentPosL++));
+ }
+ }
+ int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ];
+ if (zzNext == -1) break zzForAction;
+ zzState = zzNext;
+
+ int zzAttributes = zzAttrL[zzState];
+ if ( (zzAttributes & 1) == 1 ) {
+ zzAction = zzState;
+ zzMarkedPosL = zzCurrentPosL;
+ if ( (zzAttributes & 8) == 8 ) break zzForAction;
+ }
+
+ }
+ }
+
+ // store back cached position
+ zzMarkedPos = zzMarkedPosL;
+
+ switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
+ case 2:
+ { return JavaTokenType.WHITE_SPACE;
+ }
+ case 6: break;
+ case 5:
+ { return JavaTokenType.DOT;
+ }
+ case 7: break;
+ case 3:
+ { return JavaTokenType.IDENTIFIER;
+ }
+ case 8: break;
+ case 4:
+ { return JavaTokenType.END_OF_LINE_COMMENT;
+ }
+ case 9: break;
+ case 1:
+ { return JavaTokenType.BAD_CHARACTER;
+ }
+ case 10: break;
+ default:
+ if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
+ zzAtEOF = true;
+ zzDoEOF();
+ return null;
+ }
+ else {
+ zzScanError(ZZ_NO_MATCH);
+ }
+ }
+ }
+ }
+
+
+}
diff --git a/java/java-impl/src/com/intellij/spi/psi/SPIFile.java b/java/java-impl/src/com/intellij/spi/psi/SPIFile.java
new file mode 100644
index 000000000000..9f1e8106878a
--- /dev/null
+++ b/java/java-impl/src/com/intellij/spi/psi/SPIFile.java
@@ -0,0 +1,97 @@
+/*
+ * 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 com.intellij.spi.psi;
+
+import com.intellij.extapi.psi.PsiFileBase;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.*;
+import com.intellij.psi.util.ClassUtil;
+import com.intellij.spi.SPIFileType;
+import com.intellij.lang.spi.SPILanguage;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * User: anna
+ */
+public class SPIFile extends PsiFileBase {
+ public SPIFile(@NotNull FileViewProvider viewProvider) {
+ super(viewProvider, SPILanguage.INSTANCE);
+ }
+
+ @Override
+ public PsiReference getReference() {
+ return new SPIFileName2ClassReference(this, ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+ @Override
+ public PsiClass compute() {
+ return ClassUtil.findPsiClass(getManager(), getName(), null, true, getResolveScope());
+ }
+ }));
+ }
+
+ @NotNull
+ @Override
+ public FileType getFileType() {
+ return SPIFileType.INSTANCE;
+ }
+
+ private static class SPIFileName2ClassReference extends PsiReferenceBase<PsiFile> {
+ private final PsiClass myClass;
+
+ public SPIFileName2ClassReference(PsiFile file, PsiClass aClass) {
+ super(file, new TextRange(0, 0), false);
+ myClass = aClass;
+ }
+
+ @Nullable
+ @Override
+ public PsiElement resolve() {
+ return myClass;
+ }
+
+ @Override
+ public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
+ final String className = ClassUtil.getJVMClassName(myClass);
+ if (className != null) {
+ final String newFileName = className.substring(0, className.lastIndexOf(myClass.getName())) + newElementName;
+ return getElement().setName(newFileName);
+ }
+ return getElement();
+ }
+
+ @Override
+ public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
+ if (element instanceof PsiClass) {
+ final String className = ClassUtil.getJVMClassName((PsiClass)element);
+ if (className != null) {
+ return getElement().setName(className);
+ }
+ }
+ return getElement();
+ }
+
+ @NotNull
+ @Override
+ public Object[] getVariants() {
+ return ArrayUtil.EMPTY_OBJECT_ARRAY;
+ }
+ }
+}
diff --git a/java/java-impl/src/com/intellij/spi/psi/SPIProviderElement.java b/java/java-impl/src/com/intellij/spi/psi/SPIProviderElement.java
new file mode 100644
index 000000000000..17c47b0ffbcc
--- /dev/null
+++ b/java/java-impl/src/com/intellij/spi/psi/SPIProviderElement.java
@@ -0,0 +1,127 @@
+/*
+ * 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 com.intellij.spi.psi;
+
+import com.intellij.extapi.psi.ASTWrapperPsiElement;
+import com.intellij.lang.ASTNode;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.*;
+import com.intellij.psi.infos.ClassCandidateInfo;
+import com.intellij.psi.scope.PsiScopeProcessor;
+import com.intellij.psi.util.ClassUtil;
+import com.intellij.spi.SPIFileType;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * User: anna
+ */
+public class SPIProviderElement extends ASTWrapperPsiElement implements PsiJavaReference {
+ public SPIProviderElement(ASTNode node) {
+ super(node);
+ }
+
+ @Override
+ public void processVariants(PsiScopeProcessor processor) {
+ }
+
+ @NotNull
+ @Override
+ public JavaResolveResult advancedResolve(boolean incompleteCode) {
+ final PsiElement resolve = resolve();
+ if (resolve instanceof PsiClass) {
+ return new ClassCandidateInfo(resolve, PsiSubstitutor.EMPTY);
+ }
+ return JavaResolveResult.EMPTY;
+ }
+
+ @NotNull
+ @Override
+ public JavaResolveResult[] multiResolve(boolean incompleteCode) {
+ final PsiElement resolve = resolve();
+ if (resolve instanceof PsiClass) {
+ return new JavaResolveResult[]{new ClassCandidateInfo(resolve, PsiSubstitutor.EMPTY)};
+ }
+ return JavaResolveResult.EMPTY_ARRAY;
+ }
+
+ @Override
+ public PsiElement getElement() {
+ return this;
+ }
+
+ @Override
+ public TextRange getRangeInElement() {
+ return new TextRange(0, getTextLength());
+ }
+
+ @Nullable
+ @Override
+ public PsiElement resolve() {
+ return ClassUtil.findPsiClass(getManager(), getText(), null, true, getResolveScope());
+ }
+
+ @NotNull
+ @Override
+ public String getCanonicalText() {
+ return getText();
+ }
+
+ @Override
+ public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
+ final SPIProvidersElementList firstChild =
+ (SPIProvidersElementList)PsiFileFactory.getInstance(getProject())
+ .createFileFromText("spi_dummy", SPIFileType.INSTANCE, newElementName).getFirstChild();
+ return replace(firstChild.getElements().get(0));
+ }
+
+ @Override
+ public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
+ if (element instanceof PsiClass) {
+ final String className = ClassUtil.getJVMClassName((PsiClass)element);
+ if (className != null) {
+ return handleElementRename(className);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isReferenceTo(PsiElement element) {
+ if (element instanceof PsiClass) {
+ return getText().equals(ClassUtil.getJVMClassName((PsiClass)element));
+ }
+ return false;
+ }
+
+ @NotNull
+ @Override
+ public Object[] getVariants() {
+ return ArrayUtil.EMPTY_OBJECT_ARRAY;
+ }
+
+ @Override
+ public PsiReference getReference() {
+ return this;
+ }
+
+ @Override
+ public boolean isSoft() {
+ return false;
+ }
+}
diff --git a/java/java-impl/src/com/intellij/spi/psi/SPIProvidersElementList.java b/java/java-impl/src/com/intellij/spi/psi/SPIProvidersElementList.java
new file mode 100644
index 000000000000..75cc44cb700f
--- /dev/null
+++ b/java/java-impl/src/com/intellij/spi/psi/SPIProvidersElementList.java
@@ -0,0 +1,37 @@
+/*
+ * 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 com.intellij.spi.psi;
+
+import com.intellij.extapi.psi.ASTWrapperPsiElement;
+import com.intellij.lang.ASTNode;
+import com.intellij.spi.parsing.SPIElementType;
+import com.intellij.spi.parsing.SPIElementTypes;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * User: anna
+ */
+public class SPIProvidersElementList extends ASTWrapperPsiElement {
+ public SPIProvidersElementList(@NotNull ASTNode node) {
+ super(node);
+ }
+
+ public List<SPIProviderElement> getElements() {
+ return findChildrenByType(SPIElementTypes.PROVIDER);
+ }
+}