| /* |
| * 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.psi.search.scope.packageSet; |
| |
| import com.intellij.analysis.AnalysisScopeBundle; |
| import com.intellij.lexer.Lexer; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.extensions.Extensions; |
| import com.intellij.psi.TokenType; |
| import com.intellij.psi.search.scope.packageSet.lexer.ScopeTokenTypes; |
| import com.intellij.psi.search.scope.packageSet.lexer.ScopesLexer; |
| import org.jetbrains.annotations.Nullable; |
| |
| public class PackageSetFactoryImpl extends PackageSetFactory { |
| private static final Logger LOG = Logger.getInstance("#com.intellij.psi.search.scope.packageSet.PackageSetFactoryImpl"); |
| |
| @Override |
| public PackageSet compile(String text) throws ParsingException { |
| Lexer lexer = new ScopesLexer(); |
| lexer.start(text); |
| return new Parser(lexer).parse(); |
| } |
| |
| private static class Parser { |
| private final Lexer myLexer; |
| |
| public Parser(Lexer lexer) { |
| myLexer = lexer; |
| } |
| |
| public PackageSet parse() throws ParsingException { |
| PackageSet set = parseUnion(); |
| if (myLexer.getTokenType() != null) error(AnalysisScopeBundle.message("error.packageset.token.expectations", getTokenText())); |
| return set; |
| } |
| |
| private PackageSet parseUnion() throws ParsingException { |
| PackageSet result = parseIntersection(); |
| while (true) { |
| if (myLexer.getTokenType() != ScopeTokenTypes.OROR) break; |
| myLexer.advance(); |
| result = new UnionPackageSet(result, parseIntersection()); |
| } |
| return result; |
| } |
| |
| private PackageSet parseIntersection() throws ParsingException { |
| PackageSet result = parseTerm(); |
| while (true) { |
| if (myLexer.getTokenType() != ScopeTokenTypes.ANDAND) break; |
| myLexer.advance(); |
| result = new IntersectionPackageSet(result, parseTerm()); |
| } |
| return result; |
| } |
| |
| private PackageSet parseTerm() throws ParsingException { |
| if (myLexer.getTokenType() == ScopeTokenTypes.EXCL) { |
| myLexer.advance(); |
| return new ComplementPackageSet(parseTerm()); |
| } |
| |
| if (myLexer.getTokenType() == ScopeTokenTypes.LPARENTH) return parseParenthesized(); |
| if (myLexer.getTokenType() == ScopeTokenTypes.IDENTIFIER && myLexer.getBufferSequence().charAt(myLexer.getTokenStart()) == '$') { |
| NamedPackageSetReference namedPackageSetReference = new NamedPackageSetReference(getTokenText()); |
| myLexer.advance(); |
| return namedPackageSetReference; |
| } |
| return parsePattern(); |
| } |
| |
| private PackageSet parsePattern() throws ParsingException { |
| String scope = null; |
| for (PackageSetParserExtension extension : Extensions.getExtensions(PackageSetParserExtension.EP_NAME)) { |
| scope = extension.parseScope(myLexer); |
| if (scope != null) break; |
| } |
| if (scope == null) error("Unknown scope type"); |
| String modulePattern = parseModulePattern(); |
| |
| if (myLexer.getTokenType() == ScopeTokenTypes.COLON) { |
| myLexer.advance(); |
| } |
| for (PackageSetParserExtension extension : Extensions.getExtensions(PackageSetParserExtension.EP_NAME)) { |
| final PackageSet packageSet = extension.parsePackageSet(myLexer, scope, modulePattern); |
| if (packageSet != null) return packageSet; |
| } |
| error("Unknown scope type"); |
| return null; //not reachable |
| } |
| |
| private String getTokenText() { |
| int start = myLexer.getTokenStart(); |
| int end = myLexer.getTokenEnd(); |
| return myLexer.getBufferSequence().subSequence(start, end).toString(); |
| } |
| |
| @Nullable |
| private String parseModulePattern() throws ParsingException { |
| if (myLexer.getTokenType() != ScopeTokenTypes.LBRACKET) return null; |
| myLexer.advance(); |
| StringBuffer pattern = new StringBuffer(); |
| while (true) { |
| if (myLexer.getTokenType() == ScopeTokenTypes.RBRACKET || |
| myLexer.getTokenType() == null) { |
| myLexer.advance(); |
| break; |
| } else if (myLexer.getTokenType() == ScopeTokenTypes.ASTERISK) { |
| pattern.append("*"); |
| } else if (myLexer.getTokenType() == ScopeTokenTypes.IDENTIFIER || |
| myLexer.getTokenType() == TokenType.WHITE_SPACE || |
| myLexer.getTokenType() == ScopeTokenTypes.INTEGER_LITERAL ) { |
| pattern.append(getTokenText()); |
| } else if (myLexer.getTokenType() == ScopeTokenTypes.DOT) { |
| pattern.append("."); |
| } else if (myLexer.getTokenType() == ScopeTokenTypes.MINUS) { |
| pattern.append("-"); |
| } else if (myLexer.getTokenType() == ScopeTokenTypes.TILDE) { |
| pattern.append("~"); |
| } else if (myLexer.getTokenType() == ScopeTokenTypes.SHARP) { |
| pattern.append("#"); |
| } |
| else if (myLexer.getTokenType() == ScopeTokenTypes.COLON) { |
| pattern.append(":"); |
| } else { |
| pattern.append(getTokenText()); |
| } |
| myLexer.advance(); |
| } |
| if (pattern.length() == 0) { |
| error(AnalysisScopeBundle.message("error.packageset.pattern.expectations")); |
| } |
| return pattern.toString(); |
| } |
| |
| private PackageSet parseParenthesized() throws ParsingException { |
| LOG.assertTrue(myLexer.getTokenType() == ScopeTokenTypes.LPARENTH); |
| myLexer.advance(); |
| |
| PackageSet result = parseUnion(); |
| if (myLexer.getTokenType() != ScopeTokenTypes.RPARENTH) error(AnalysisScopeBundle.message("error.packageset.rparen.expected")); |
| myLexer.advance(); |
| |
| return result; |
| } |
| |
| private void error(String message) throws ParsingException { |
| throw new ParsingException( |
| AnalysisScopeBundle.message("error.packageset.position.parsing.error", message, (myLexer.getTokenStart() + 1))); |
| } |
| } |
| } |