Merge branch 'master' of git@git.labs.intellij.net:idea/community

This commit is contained in:
Kirill Kalishev
2010-12-16 16:15:39 +03:00
118 changed files with 2169 additions and 881 deletions
+9
View File
@@ -77,6 +77,15 @@
<orderEntry type="module" module-name="IntelliLang-javaee" />
<orderEntry type="module" module-name="IntelliLang-xml" />
<orderEntry type="module" module-name="xpath" />
<orderEntry type="module" module-name="tasks-core" />
<orderEntry type="module" module-name="jira-connector" />
<orderEntry type="module" module-name="tasks-api" />
<orderEntry type="module" module-name="tasks-java" />
<orderEntry type="module" module-name="tasks-tests" />
<orderEntry type="module" module-name="github" />
<orderEntry type="module" module-name="hg4idea" />
<orderEntry type="module" module-name="android" />
<orderEntry type="module" module-name="relaxng" />
</component>
</module>
@@ -1038,12 +1038,12 @@ public class CompileDriver {
generatedTypes.addAll(compilerManager.getRegisteredOutputTypes(compiler));
}
if (_context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
throw new ExitException(ExitStatus.ERRORS);
}
didSomething |= compiledSomething;
compiledSomethingForThisChunk |= didSomething;
if (_context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
break; // break the loop over compilers
}
}
final boolean hasUnprocessedTraverseRoots = context.getDependencyCache().hasUnprocessedTraverseRoots();
@@ -351,7 +351,7 @@ public class DebugProcessEvents extends DebugProcessImpl {
//noinspection HardCodedStringLiteral
RequestHint hint = (RequestHint)event.request().getProperty("hint");
deleteStepRequests();
deleteStepRequests(event.thread());
boolean shouldResume = false;
@@ -353,12 +353,13 @@ public abstract class DebugProcessImpl implements DebugProcess {
return;
}
try {
final ThreadReference stepThreadReference = stepThread.getThreadReference();
if (LOG.isDebugEnabled()) {
LOG.debug("DO_STEP: creating step request for " + stepThread.getThreadReference());
LOG.debug("DO_STEP: creating step request for " + stepThreadReference);
}
deleteStepRequests();
deleteStepRequests(stepThreadReference);
EventRequestManager requestManager = getVirtualMachineProxy().eventRequestManager();
StepRequest stepRequest = requestManager.createStepRequest(stepThread.getThreadReference(), StepRequest.STEP_LINE, depth);
StepRequest stepRequest = requestManager.createStepRequest(stepThreadReference, StepRequest.STEP_LINE, depth);
DebuggerSettings settings = DebuggerSettings.getInstance();
if (!(hint != null && hint.isIgnoreFilters()) /*&& depth == StepRequest.STEP_INTO*/) {
final List<ClassFilter> activeFilters = new ArrayList<ClassFilter>();
@@ -404,7 +405,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
}
}
void deleteStepRequests() {
void deleteStepRequests(@Nullable final ThreadReference stepThread) {
EventRequestManager requestManager = getVirtualMachineProxy().eventRequestManager();
List<StepRequest> stepRequests = requestManager.stepRequests();
if (stepRequests.size() > 0) {
@@ -412,7 +413,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
for (final StepRequest request : stepRequests) {
ThreadReference threadReference = request.thread();
// [jeka] on attempt to delete a request assigned to a thread with unknown status, a JDWP error occures
if (threadReference.status() != ThreadReference.THREAD_STATUS_UNKNOWN) {
if (threadReference.status() != ThreadReference.THREAD_STATUS_UNKNOWN && (stepThread == null || stepThread.equals(threadReference))) {
toDelete.add(request);
}
}
@@ -298,7 +298,8 @@ public class SuspendManagerImpl implements SuspendManager {
}
myDebugProcess.logThreads();
myDebugProcess.cancelRunToCursorBreakpoint();
myDebugProcess.deleteStepRequests();
final ThreadReferenceProxyImpl thread = suspendContext.getThread();
myDebugProcess.deleteStepRequests(thread != null? thread.getThreadReference() : null);
notifyPaused(suspendContext);
}
}
@@ -127,59 +127,55 @@ public class LineBreakpoint extends BreakpointWithHighlighter {
if (!isInScopeOf(debugProcess, classType.name())) {
return;
}
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
try {
List<Location> locs = debugProcess.getPositionManager().locationsOfLine(classType, getSourcePosition());
if (locs.size() > 0) {
for (final Location location : locs) {
if (LOG.isDebugEnabled()) {
LOG.debug("Found location for reference type " + classType.name() + " at line " + getLineIndex() + "; isObsolete: " + (debugProcess.getVirtualMachineProxy().versionHigher("1.4") && location.method().isObsolete()));
}
BreakpointRequest request = debugProcess.getRequestsManager().createBreakpointRequest(LineBreakpoint.this, location);
debugProcess.getRequestsManager().enableRequest(request);
if (LOG.isDebugEnabled()) {
LOG.debug("Created breakpoint request for reference type " + classType.name() + " at line " + getLineIndex());
}
}
}
else {
// there's no executable code in this class
debugProcess.getRequestsManager().setInvalid(LineBreakpoint.this, DebuggerBundle.message(
"error.invalid.breakpoint.no.executable.code", (getLineIndex() + 1), classType.name())
);
if (LOG.isDebugEnabled()) {
LOG.debug("No locations of type " + classType.name() + " found at line " + getLineIndex());
}
}
}
catch (ClassNotPreparedException ex) {
try {
List<Location> locs = debugProcess.getPositionManager().locationsOfLine(classType, getSourcePosition());
if (locs.size() > 0) {
for (final Location location : locs) {
if (LOG.isDebugEnabled()) {
LOG.debug("ClassNotPreparedException: " + ex.getMessage());
LOG.debug("Found location for reference type " + classType.name() + " at line " + getLineIndex() + "; isObsolete: " + (debugProcess.getVirtualMachineProxy().versionHigher("1.4") && location.method().isObsolete()));
}
// there's a chance to add a breakpoint when the class is prepared
}
catch (ObjectCollectedException ex) {
BreakpointRequest request = debugProcess.getRequestsManager().createBreakpointRequest(LineBreakpoint.this, location);
debugProcess.getRequestsManager().enableRequest(request);
if (LOG.isDebugEnabled()) {
LOG.debug("ObjectCollectedException: " + ex.getMessage());
LOG.debug("Created breakpoint request for reference type " + classType.name() + " at line " + getLineIndex());
}
// there's a chance to add a breakpoint when the class is prepared
}
catch (InvalidLineNumberException ex) {
if (LOG.isDebugEnabled()) {
LOG.debug("InvalidLineNumberException: " + ex.getMessage());
}
debugProcess.getRequestsManager().setInvalid(LineBreakpoint.this, DebuggerBundle.message("error.invalid.breakpoint.bad.line.number"));
}
catch (InternalException ex) {
LOG.info(ex);
}
catch(Exception ex) {
LOG.info(ex);
}
updateUI();
}
});
else {
// there's no executable code in this class
debugProcess.getRequestsManager().setInvalid(LineBreakpoint.this, DebuggerBundle.message(
"error.invalid.breakpoint.no.executable.code", (getLineIndex() + 1), classType.name())
);
if (LOG.isDebugEnabled()) {
LOG.debug("No locations of type " + classType.name() + " found at line " + getLineIndex());
}
}
}
catch (ClassNotPreparedException ex) {
if (LOG.isDebugEnabled()) {
LOG.debug("ClassNotPreparedException: " + ex.getMessage());
}
// there's a chance to add a breakpoint when the class is prepared
}
catch (ObjectCollectedException ex) {
if (LOG.isDebugEnabled()) {
LOG.debug("ObjectCollectedException: " + ex.getMessage());
}
// there's a chance to add a breakpoint when the class is prepared
}
catch (InvalidLineNumberException ex) {
if (LOG.isDebugEnabled()) {
LOG.debug("InvalidLineNumberException: " + ex.getMessage());
}
debugProcess.getRequestsManager().setInvalid(LineBreakpoint.this, DebuggerBundle.message("error.invalid.breakpoint.bad.line.number"));
}
catch (InternalException ex) {
LOG.info(ex);
}
catch(Exception ex) {
LOG.info(ex);
}
updateUI();
}
private boolean isInScopeOf(DebugProcessImpl debugProcess, String className) {
@@ -132,6 +132,7 @@ public class AllClassesGetter {
start--;
}
context.getDocument().replaceString(start + 1, context.getTailOffset(), qName);
LOG.assertTrue(context.getTailOffset() >= 0);
}
}
};
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.AutoPopupController;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.ExpectedTypesProvider;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -94,7 +95,18 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
JavaCompletionUtil.insertParentheses(context, item, false, true);
AutoPopupController.getInstance(project).autoPopupParameterInfo(editor, null);
}
LOG.assertTrue(context.getTailOffset() >= 0);
String docText = context.getDocument().getText();
DefaultInsertHandler.addImportForItem(context.getFile(), context.getStartOffset(), item);
if (context.getTailOffset() < 0) {
if (ApplicationManagerEx.getApplicationEx().isInternal()) {
LOG.error("Tail offset degraded: " + context.getStartOffset() + "; " + docText);
} else {
LOG.error("Tail offset degraded after insertion");
}
}
if (annotation) {
// Check if someone inserts annotation class that require @
@@ -923,14 +923,21 @@ public class JavaCompletionUtil {
public static void insertParentheses(final InsertionContext context, final LookupElement item, boolean overloadsMatter, boolean hasParams) {
final Editor editor = context.getEditor();
final TailType tailType = getTailType(item, context);
final char completionChar = context.getCompletionChar();
final PsiFile file = context.getFile();
final TailType tailType = completionChar == '(' ? TailType.NONE : LookupItem.handleCompletionChar(context.getEditor(), item, completionChar);
final boolean hasTail = tailType != TailType.NONE && tailType != TailType.UNKNOWN;
final boolean smart = completionChar == Lookup.COMPLETE_STATEMENT_SELECT_CHAR;
final boolean addCompletionChar = context.shouldAddCompletionChar();
context.setAddCompletionChar(false);
final boolean needLeftParenth = isToInsertParenth(file.findElementAt(context.getStartOffset()));
final boolean needRightParenth = tailType != TailType.SMART_COMPLETION && CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET;
final boolean needRightParenth = !smart && (CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET || hasTail);
if (hasTail) {
hasParams = false;
}
if (needLeftParenth) {
final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(context.getProject());
@@ -947,42 +954,20 @@ public class JavaCompletionUtil {
AutoPopupController.getInstance(file.getProject()).autoPopupParameterInfo(editor, overloadsMatter ? null : (PsiElement)item.getObject());
}
if (tailType == TailType.SEMICOLON) {
if (!needRightParenth) {
return;
}
PsiDocumentManager.getInstance(file.getProject()).commitAllDocuments();
if (psiElement().beforeLeaf(psiElement().withText(".")).accepts(file.findElementAt(context.getTailOffset() - 1))) {
return;
if (smart || needLeftParenth && needRightParenth && addCompletionChar) {
TailType toInsert = tailType;
LookupItem lookupItem = item.as(LookupItem.class);
if (lookupItem == null || lookupItem.getAttribute(LookupItem.TAIL_TYPE_ATTR) != TailType.UNKNOWN) {
if (!hasTail && item.getObject() instanceof PsiMethod && ((PsiMethod)item.getObject()).getReturnType() == PsiType.VOID) {
PsiDocumentManager.getInstance(file.getProject()).commitAllDocuments();
if (psiElement().beforeLeaf(psiElement().withText(".")).accepts(file.findElementAt(context.getTailOffset() - 1))) {
return;
}
toInsert = TailType.SEMICOLON;
}
}
toInsert.processTail(editor, context.getTailOffset());
}
if (tailType == TailType.SMART_COMPLETION || needLeftParenth && needRightParenth) {
tailType.processTail(editor, context.getTailOffset());
}
}
@NotNull
public static TailType getTailType(final LookupElement item, InsertionContext context) {
final char completionChar = context.getCompletionChar();
if (completionChar == '!') return item instanceof LookupItem ? ((LookupItem)item).getTailType() : TailType.NONE;
if (completionChar == '(') {
final Object o = item.getObject();
if (o instanceof PsiMethod) {
final PsiMethod psiMethod = (PsiMethod)o;
return psiMethod.getParameterList().getParameters().length > 0 || psiMethod.getReturnType() != PsiType.VOID
? TailType.NONE : TailType.SEMICOLON;
} else if (o instanceof PsiClass) { // it may be a constructor
return TailType.NONE;
}
}
if (completionChar == Lookup.COMPLETE_STATEMENT_SELECT_CHAR) return TailType.SMART_COMPLETION;
if (!context.shouldAddCompletionChar()) {
return TailType.NONE;
}
return LookupItem.handleCompletionChar(context.getEditor(), item, completionChar);
}
public static boolean isToInsertParenth(PsiElement place){
@@ -17,7 +17,6 @@ package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.ExpectedTypesProvider;
import com.intellij.codeInsight.TailType;
import com.intellij.codeInsight.completion.util.MethodParenthesesHandler;
import com.intellij.codeInsight.lookup.*;
import com.intellij.codeInsight.lookup.impl.JavaElementLookupRenderer;
@@ -57,8 +56,6 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
LOG.error(method.getName());
}
myCanImportStatic = canImportStatic;
PsiType type = method.getReturnType();
setTailType(PsiType.VOID.equals(type) ? TailType.SEMICOLON : TailType.NONE);
}
public PsiType getType() {
@@ -138,7 +138,7 @@ public class RemoveSuppressWarningAction implements LocalQuickFix {
}
else if (newText != null) {
newText = "@" + SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME + " " + newText;
PsiDocTag newTag = JavaPsiFacade.getInstance(tag.getProject()).getElementFactory().createDocTagFromText(newText, tag);
PsiDocTag newTag = JavaPsiFacade.getInstance(tag.getProject()).getElementFactory().createDocTagFromText(newText);
tag.replace(newTag);
}
}
@@ -84,7 +84,7 @@ public class SuppressAllForClassFix extends SuppressFix {
PsiDocTag noInspectionTag = docComment.findTagByName(SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME);
if (noInspectionTag != null) {
String tagText = "@" + SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME + " " + SuppressionUtil.ALL;
noInspectionTag.replace(JavaPsiFacade.getInstance(project).getElementFactory().createDocTagFromText(tagText, null));
noInspectionTag.replace(JavaPsiFacade.getInstance(project).getElementFactory().createDocTagFromText(tagText));
DaemonCodeAnalyzer.getInstance(project).restart();
return;
}
@@ -109,7 +109,7 @@ public class SuppressFix extends SuppressIntentionAction {
PsiManager manager = PsiManager.getInstance(project);
if (docComment == null) {
String commentText = "/** @" + SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME + " " + getID(container) + "*/";
docComment = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createDocCommentFromText(commentText, null);
docComment = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createDocCommentFromText(commentText);
PsiElement firstChild = container.getFirstChild();
container.addBefore(docComment, firstChild);
}
@@ -122,11 +122,11 @@ public class SuppressFix extends SuppressIntentionAction {
" " +
(valueElement != null ? valueElement.getText() + "," : "") +
getID(container);
noInspectionTag.replace(JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createDocTagFromText(tagText, null));
noInspectionTag.replace(JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createDocTagFromText(tagText));
}
else {
String tagText = "@" + SuppressionUtil.SUPPRESS_INSPECTIONS_TAG_NAME + " " + getID(container);
docComment.add(JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createDocTagFromText(tagText, null));
docComment.add(JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createDocTagFromText(tagText));
}
}
}
@@ -176,7 +176,7 @@ public class VariableAccessFromInnerClassFix implements IntentionAction {
variableDeclarationStatement = factory.createVariableDeclarationStatement(variable.getName(), newType, init);
}
else {
PsiExpression init = factory.createExpressionFromText(" { " + initializer.getText() + " }", variable);
PsiExpression init = factory.createExpressionFromText("{ " + initializer.getText() + " }", variable);
variableDeclarationStatement = factory.createVariableDeclarationStatement(variable.getName(), newType, init);
}
PsiVariable newVariable = (PsiVariable)variableDeclarationStatement.getDeclaredElements()[0];
@@ -177,7 +177,7 @@ public class ConvertToBasicLatinAction extends PsiElementBaseIntentionAction {
}
public PsiElement createReplacement(final PsiElement element, final String newText) {
return JavaPsiFacade.getElementFactory(element.getProject()).createDocCommentFromText(newText, element.getParent());
return JavaPsiFacade.getElementFactory(element.getProject()).createDocCommentFromText(newText);
}
private static void loadEntities(final Project project) {
@@ -145,8 +145,18 @@ public class SplitDeclarationAction extends PsiElementBaseIntentionAction {
}
}
block.getParent().addBefore(varDeclStatement, block);
final PsiElement parent = block.getParent();
decl.replace(statement);
if (!(parent instanceof PsiCodeBlock)) {
final PsiBlockStatement blockStatement =
(PsiBlockStatement)JavaPsiFacade.getElementFactory(project).createStatementFromText("{}", null);
final PsiCodeBlock codeBlock = blockStatement.getCodeBlock();
codeBlock.add(varDeclStatement);
codeBlock.add(block);
block.replace(blockStatement);
} else {
parent.addBefore(varDeclStatement, block);
}
} else {
block.addAfter(statement, decl);
}
@@ -1343,9 +1343,8 @@ public class JavaDocInfoGenerator {
}
else {
try {
final PsiDocTag tag = JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createDocCommentFromText("/** @exception " + paramName + " */",
method.getContainingFile()).getTags()[0];
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory();
final PsiDocTag tag = elementFactory.createDocTagFromText("@exception " + paramName);
collectedTags.addLast(new Pair<PsiDocTag, InheritDocProvider<PsiDocTag>>(tag, ourEmptyProvider));
}
catch (IncorrectOperationException e) {
@@ -323,7 +323,7 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool {
if (owner != null) {
if (!CodeInsightUtil.preparePsiElementsForWrite(owner)) return;
final PsiDocComment docComment = owner.getDocComment();
final PsiDocTag tag = factory.createDocTagFromText("@" + myTag+" "+myValue, docComment);
final PsiDocTag tag = factory.createDocTagFromText("@" + myTag + " " + myValue);
if (docComment != null) {
PsiElement addedTag;
final PsiElement anchor = getAnchor();
@@ -146,7 +146,7 @@ public class DeclarationParser {
}
@Nullable
private static PsiBuilder.Marker parseEnumConstant(final PsiBuilder builder) {
public static PsiBuilder.Marker parseEnumConstant(final PsiBuilder builder) {
final PsiBuilder.Marker constant = builder.mark();
parseModifierList(builder);
@@ -184,13 +184,18 @@ public class JavaParserUtil {
return builder;
}
@Nullable
public static ASTNode parseFragment(final ASTNode chameleon, final ParserWrapper wrapper) {
return parseFragment(chameleon, wrapper, true, LanguageLevel.HIGHEST);
}
@Nullable
public static ASTNode parseFragment(final ASTNode chameleon, final ParserWrapper wrapper, final boolean eatAll, final LanguageLevel level) {
final PsiElement psi = (chameleon.getTreeParent() != null ? chameleon.getTreeParent().getPsi() : chameleon.getPsi());
assert psi != null : chameleon;
final Project project = psi.getProject();
final PsiBuilderFactory factory = PsiBuilderFactory.getInstance();
final LanguageLevel level = LanguageLevel.HIGHEST;
final Lexer lexer = JavaParserDefinition.createLexer(level);
final PsiBuilder builder = factory.createBuilder(project, chameleon, lexer, chameleon.getElementType().getLanguage(), chameleon.getChars());
setLanguageLevel(builder, level);
@@ -198,6 +203,7 @@ public class JavaParserUtil {
final PsiBuilder.Marker root = builder.mark();
wrapper.parse(builder);
if (!builder.eof()) {
if (!eatAll) throw new AssertionError("Unexpected tokens");
final PsiBuilder.Marker extras = builder.mark();
while (!builder.eof()) builder.advanceLexer();
extras.error(JavaErrorMessages.message("unexpected.tokens"));
@@ -389,4 +395,4 @@ public class JavaParserUtil {
myDelegate.putUserDataUnprotected(key, value);
}
}
}
}
@@ -311,7 +311,7 @@ public class ReferenceParser {
}
@Nullable
private static PsiBuilder.Marker parseTypeParameter(final PsiBuilder builder) {
public static PsiBuilder.Marker parseTypeParameter(final PsiBuilder builder) {
final PsiBuilder.Marker param = builder.mark();
DeclarationParser.parseAnnotations(builder);
@@ -165,7 +165,7 @@ public class StatementParser {
}
@Nullable
private static PsiBuilder.Marker parseStatement(final PsiBuilder builder) {
public static PsiBuilder.Marker parseStatement(final PsiBuilder builder) {
final IElementType tokenType = builder.getTokenType();
// todo: custom parsers (?)
@@ -637,7 +637,8 @@ public class StatementParser {
return statement;
}
private static boolean parseCatchBlock(final PsiBuilder builder) {
public static boolean parseCatchBlock(final PsiBuilder builder) {
assert builder.getTokenType() == JavaTokenType.CATCH_KEYWORD : builder.getTokenType();
final PsiBuilder.Marker section = builder.mark();
builder.advanceLexer();
@@ -17,7 +17,6 @@ package com.intellij.psi.impl;
import com.intellij.lang.*;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
@@ -27,12 +26,15 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.impl.light.*;
import com.intellij.psi.impl.source.*;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.impl.source.tree.FileElement;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -41,30 +43,14 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.Map;
import static com.intellij.openapi.util.text.StringUtil.join;
public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements PsiElementFactory {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiElementFactoryImpl");
private PsiClass myArrayClass;
private PsiClass myArrayClass15;
private PsiJavaFile myDummyJavaFile;
private PsiClass ARRAY_CLASS;
private PsiClass ARRAY_CLASS15;
static {
initPrimitiveTypes();
}
private static void initPrimitiveTypes() {
ourPrimitiveTypesMap.put(PsiType.BYTE.getCanonicalText(), (PsiPrimitiveType)PsiType.BYTE);
ourPrimitiveTypesMap.put(PsiType.CHAR.getCanonicalText(), (PsiPrimitiveType)PsiType.CHAR);
ourPrimitiveTypesMap.put(PsiType.DOUBLE.getCanonicalText(), (PsiPrimitiveType)PsiType.DOUBLE);
ourPrimitiveTypesMap.put(PsiType.FLOAT.getCanonicalText(), (PsiPrimitiveType)PsiType.FLOAT);
ourPrimitiveTypesMap.put(PsiType.INT.getCanonicalText(), (PsiPrimitiveType)PsiType.INT);
ourPrimitiveTypesMap.put(PsiType.LONG.getCanonicalText(), (PsiPrimitiveType)PsiType.LONG);
ourPrimitiveTypesMap.put(PsiType.SHORT.getCanonicalText(), (PsiPrimitiveType)PsiType.SHORT);
ourPrimitiveTypesMap.put(PsiType.BOOLEAN.getCanonicalText(), (PsiPrimitiveType)PsiType.BOOLEAN);
ourPrimitiveTypesMap.put(PsiType.VOID.getCanonicalText(), (PsiPrimitiveType)PsiType.VOID);
ourPrimitiveTypesMap.put(PsiType.NULL.getCanonicalText(), (PsiPrimitiveType)PsiType.NULL);
}
public PsiElementFactoryImpl(PsiManagerEx manager) {
public PsiElementFactoryImpl(final PsiManagerEx manager) {
super(manager);
}
@@ -77,32 +63,29 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
}
@NotNull
public PsiClass getArrayClass(@NotNull LanguageLevel languageLevel) {
try {
if (languageLevel.compareTo(LanguageLevel.JDK_1_5) < 0) {
if (ARRAY_CLASS == null) {
ARRAY_CLASS = createClassFromText("public class __Array__{\n public final int length; \n public Object clone(){}\n}", null).getInnerClasses()[0];
}
return ARRAY_CLASS;
}
else {
if (ARRAY_CLASS15 == null) {
ARRAY_CLASS15 = createClassFromText("public class __Array__<T>{\n public final int length; \n public T[] clone(){}\n}", null).getInnerClasses()[0];
}
return ARRAY_CLASS15;
public PsiClass getArrayClass(@NotNull final LanguageLevel languageLevel) {
if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_5)) {
if (myArrayClass == null) {
final String body = "public class __Array__{\n public final int length;\n public Object clone() {}\n}";
myArrayClass = createClassFromText(body, null).getInnerClasses()[0];
}
return myArrayClass;
}
catch (IncorrectOperationException e) {
LOG.error(e);
return null;
else {
if (myArrayClass15 == null) {
final String body = "public class __Array__<T>{\n public final int length;\n public T[] clone() {}\n}";
myArrayClass15 = createClassFromText(body, null).getInnerClasses()[0];
}
return myArrayClass15;
}
}
@NotNull
public PsiClassType getArrayClassType(@NotNull PsiType componentType, @NotNull final LanguageLevel languageLevel) {
PsiClass arrayClass = getArrayClass(languageLevel);
public PsiClassType getArrayClassType(@NotNull final PsiType componentType, @NotNull final LanguageLevel languageLevel) {
final PsiClass arrayClass = getArrayClass(languageLevel);
final PsiTypeParameter[] typeParameters = arrayClass.getTypeParameters();
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
PsiTypeParameter[] typeParameters = arrayClass.getTypeParameters();
if (typeParameters.length == 1) {
substitutor = substitutor.put(typeParameters[0], componentType);
}
@@ -111,305 +94,227 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
}
@NotNull
public PsiClassType createType(@NotNull PsiClass resolve, @NotNull PsiSubstitutor substitutor) {
public PsiClassType createType(@NotNull final PsiClass resolve, @NotNull final PsiSubstitutor substitutor) {
return new PsiImmediateClassType(resolve, substitutor);
}
@NotNull
public PsiClassType createType(@NotNull PsiClass resolve, @NotNull PsiSubstitutor substitutor, @NotNull LanguageLevel languageLevel) {
public PsiClassType createType(@NotNull final PsiClass resolve,
@NotNull final PsiSubstitutor substitutor,
@NotNull final LanguageLevel languageLevel) {
return new PsiImmediateClassType(resolve, substitutor, languageLevel);
}
@NotNull
public PsiClassType createType(@NotNull PsiClass resolve,
@NotNull PsiSubstitutor substitutor,
@NotNull LanguageLevel languageLevel,
@NotNull PsiAnnotation[] annotations) {
public PsiClassType createType(@NotNull final PsiClass resolve,
@NotNull final PsiSubstitutor substitutor,
@NotNull final LanguageLevel languageLevel,
@NotNull final PsiAnnotation[] annotations) {
return new PsiImmediateClassType(resolve, substitutor, languageLevel, annotations);
}
@NotNull
public PsiClass createClass(@NotNull String name) throws IncorrectOperationException {
PsiUtil.checkIsIdentifier(myManager, name);
@NonNls String text = "public class " + name + "{ }";
PsiJavaFile aFile = createDummyJavaFile(text);
PsiClass[] classes = aFile.getClasses();
if (classes.length != 1) {
throw new IncorrectOperationException();
}
return classes[0];
public PsiClass createClass(@NotNull final String name) throws IncorrectOperationException {
return createClassInner("class", name);
}
@NotNull
public PsiClass createInterface(@NotNull String name) throws IncorrectOperationException {
PsiUtil.checkIsIdentifier(myManager, name);
@NonNls String text = "public interface " + name + "{ }";
PsiJavaFile aFile = createDummyJavaFile(text);
PsiClass[] classes = aFile.getClasses();
if (classes.length != 1) {
throw new IncorrectOperationException();
}
return classes[0];
public PsiClass createInterface(@NotNull final String name) throws IncorrectOperationException {
return createClassInner("interface", name);
}
@NotNull
public PsiClass createEnum(@NotNull final String name) throws IncorrectOperationException {
return createClassInner("enum", name);
}
private PsiClass createClassInner(final String type, final String name) {
PsiUtil.checkIsIdentifier(myManager, name);
@NonNls String text = "public enum " + name + "{ }";
PsiJavaFile aFile = createDummyJavaFile(text);
PsiClass[] classes = aFile.getClasses();
final PsiJavaFile aFile = createDummyJavaFile(join("public ", type, " ", name, " { }"));
final PsiClass[] classes = aFile.getClasses();
if (classes.length != 1) {
throw new IncorrectOperationException();
throw new IncorrectOperationException("Incorrect " + type + " name \"" + name + "\".");
}
return classes[0];
}
@NotNull
public PsiTypeElement createTypeElement(@NotNull PsiType psiType) {
public PsiTypeElement createTypeElement(@NotNull final PsiType psiType) {
final LightTypeElement element = new LightTypeElement(myManager, psiType);
CodeEditUtil.setNodeGenerated(element.getNode(), true);
return element;
}
@NotNull
public PsiJavaCodeReferenceElement createReferenceElementByType(@NotNull PsiClassType type) {
public PsiJavaCodeReferenceElement createReferenceElementByType(@NotNull final PsiClassType type) {
if (type instanceof PsiClassReferenceType) {
return ((PsiClassReferenceType)type).getReference();
}
final PsiClassType.ClassResolveResult resolveResult = type.resolveGenerics();
return new LightClassReference(myManager, type.getPresentableText(), resolveResult.getElement(), resolveResult.getSubstitutor());
final PsiClass refClass = resolveResult.getElement();
assert refClass != null : type;
return new LightClassReference(myManager, type.getPresentableText(), refClass, resolveResult.getSubstitutor());
}
@NotNull
public PsiField createField(@NotNull String name, @NotNull PsiType type) throws IncorrectOperationException {
public PsiField createField(@NotNull final String name, @NotNull final PsiType type) throws IncorrectOperationException {
PsiUtil.checkIsIdentifier(myManager, name);
if (PsiType.NULL.equals(type)) {
throw new IncorrectOperationException("Cannot create field with type \"<null_type>\".");
throw new IncorrectOperationException("Cannot create field with type \"null\".");
}
TreeElement typeCopy = ChangeUtil.copyToElement(createTypeElement(type));
typeCopy.acceptTree(new GeneratedMarkerVisitor());
@NonNls String text = "class _Dummy_ {private int " + name + ";}";
PsiJavaFile aFile = createDummyJavaFile(text);
PsiClass aClass = aFile.getClasses()[0];
PsiField field = aClass.getFields()[0];
SourceTreeToPsiMap.psiElementToTree(field).replaceChild(SourceTreeToPsiMap.psiElementToTree(field.getTypeElement()), typeCopy);
ChangeUtil.decodeInformation((TreeElement)SourceTreeToPsiMap.psiElementToTree(field));
final PsiJavaFile aFile = createDummyJavaFile(join("class _Dummy_ { private ", type.getCanonicalText(), " ", name, "; }"));
final PsiField field = aFile.getClasses()[0].getFields()[0];
JavaCodeStyleManager.getInstance(myManager.getProject()).shortenClassReferences(field);
return (PsiField)CodeStyleManager.getInstance(myManager.getProject()).reformat(field);
}
@NotNull
public PsiMethod createMethod(@NotNull String name, PsiType returnType) throws IncorrectOperationException {
public PsiMethod createMethod(@NotNull final String name, final PsiType returnType) throws IncorrectOperationException {
PsiUtil.checkIsIdentifier(myManager, name);
if (PsiType.NULL.equals(returnType)) {
throw new IncorrectOperationException("Cannot create field with type \"<null_type>\".");
throw new IncorrectOperationException("Cannot create method with type \"null\".");
}
@NonNls String text = "class _Dummy_ {\n public " + returnType.getCanonicalText() + " " + name + "(){}\n}";
PsiJavaFile aFile = createDummyJavaFile(text);
PsiClass aClass = aFile.getClasses()[0];
PsiMethod method = aClass.getMethods()[0];
final PsiJavaFile aFile = createDummyJavaFile(join("class _Dummy_ { public " + returnType.getCanonicalText(), " ", name, "() {} }"));
final PsiMethod method = aFile.getClasses()[0].getMethods()[0];
JavaCodeStyleManager.getInstance(myManager.getProject()).shortenClassReferences(method);
return (PsiMethod)CodeStyleManager.getInstance(myManager.getProject()).reformat(method);
}
@NotNull
public PsiMethod createConstructor() {
try {
@NonNls String text = "class _Dummy_ {\n public _Dummy_(){}\n}";
PsiJavaFile aFile = createDummyJavaFile(text);
PsiClass aClass = aFile.getClasses()[0];
PsiMethod method = aClass.getMethods()[0];
return (PsiMethod)CodeStyleManager.getInstance(myManager.getProject()).reformat(method);
}
catch (IncorrectOperationException e) {
LOG.assertTrue(false);
return null;
}
final PsiJavaFile aFile = createDummyJavaFile("class _Dummy_ { public _Dummy_() {} }");
final PsiMethod method = aFile.getClasses()[0].getMethods()[0];
return (PsiMethod)CodeStyleManager.getInstance(myManager.getProject()).reformat(method);
}
@NotNull
public PsiClassInitializer createClassInitializer() throws IncorrectOperationException {
@NonNls String text = "class _Dummy_ { {} }";
final PsiJavaFile aFile = createDummyJavaFile(text);
final PsiClass aClass = aFile.getClasses()[0];
final PsiClassInitializer psiClassInitializer = aClass.getInitializers()[0];
return (PsiClassInitializer)CodeStyleManager.getInstance(myManager.getProject()).reformat(psiClassInitializer);
final PsiJavaFile aFile = createDummyJavaFile("class _Dummy_ { {} }");
final PsiClassInitializer classInitializer = aFile.getClasses()[0].getInitializers()[0];
return (PsiClassInitializer)CodeStyleManager.getInstance(myManager.getProject()).reformat(classInitializer);
}
@NotNull
public PsiParameter createParameter(@NotNull String name, @NotNull PsiType type) throws IncorrectOperationException {
public PsiParameter createParameter(@NotNull final String name, @NotNull final PsiType type) throws IncorrectOperationException {
PsiUtil.checkIsIdentifier(myManager, name);
if (PsiType.NULL.equals(type)) {
throw new IncorrectOperationException("Cannot create field with type \"<null_type>\".");
throw new IncorrectOperationException("Cannot create parameter with type \"null\".");
}
final FileElement treeHolder = DummyHolderFactory.createHolder(myManager, null).getTreeElement();
final String text = type.getCanonicalText() + " " + name;
final CompositeElement treeElement = getJavaParsingContext(treeHolder).getDeclarationParsing().parseParameterText(text);
if (treeElement == null) {
throw new AssertionError("Null element for text = " + text);
}
treeHolder.rawAddChildren(treeElement);
CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myManager.getProject());
PsiParameter parameter = (PsiParameter)SourceTreeToPsiMap.treeElementToPsi(treeElement);
PsiUtil.setModifierProperty(parameter, PsiModifier.FINAL, CodeStyleSettingsManager.getSettings(myManager.getProject()).GENERATE_FINAL_PARAMETERS);
treeElement.acceptTree(new GeneratedMarkerVisitor());
final String text = join(type.getCanonicalText() + " " + name);
final PsiParameter parameter = createParameterFromText(text, null);
final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myManager.getProject());
PsiUtil.setModifierProperty(parameter, PsiModifier.FINAL,
CodeStyleSettingsManager.getSettings(myManager.getProject()).GENERATE_FINAL_PARAMETERS);
markGenerated(parameter);
JavaCodeStyleManager.getInstance(myManager.getProject()).shortenClassReferences(parameter);
return (PsiParameter)codeStyleManager.reformat(parameter);
}
@NotNull
public PsiCodeBlock createCodeBlock() {
try {
PsiCodeBlock block = createCodeBlockFromText("{}", null);
return (PsiCodeBlock)CodeStyleManager.getInstance(myManager.getProject()).reformat(block);
}
catch (IncorrectOperationException e) {
LOG.error(e);
return null;
}
final PsiCodeBlock block = createCodeBlockFromText("{}", null);
return (PsiCodeBlock)CodeStyleManager.getInstance(myManager.getProject()).reformat(block);
}
@NotNull
public PsiClassType createType(@NotNull PsiClass aClass) {
public PsiClassType createType(@NotNull final PsiClass aClass) {
return new PsiImmediateClassType(aClass, aClass instanceof PsiTypeParameter ? PsiSubstitutor.EMPTY : createRawSubstitutor(aClass));
}
@NotNull
public PsiClassType createType(@NotNull PsiJavaCodeReferenceElement classReference) {
public PsiClassType createType(@NotNull final PsiJavaCodeReferenceElement classReference) {
return new PsiClassReferenceType(classReference, null);
}
@NotNull
public PsiClassType createType(@NotNull PsiClass aClass, PsiType parameter) {
PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
assert typeParameters.length == 1;
Map<PsiTypeParameter, PsiType> map = Collections.singletonMap(typeParameters[0], parameter);
public PsiClassType createType(@NotNull final PsiClass aClass, final PsiType parameter) {
final PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
assert typeParameters.length == 1 : aClass;
final Map<PsiTypeParameter, PsiType> map = Collections.singletonMap(typeParameters[0], parameter);
return createType(aClass, createSubstitutor(map));
}
@NotNull
public PsiClassType createType(@NotNull PsiClass aClass, PsiType... parameters) {
PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
public PsiClassType createType(@NotNull final PsiClass aClass, final PsiType... parameters) {
final PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
assert parameters.length == typeParameters.length;
Map<PsiTypeParameter, PsiType> map = new java.util.HashMap<PsiTypeParameter, PsiType>();
final Map<PsiTypeParameter, PsiType> map = new java.util.HashMap<PsiTypeParameter, PsiType>();
for (int i = 0; i < parameters.length; i++) {
map.put(typeParameters[i], parameters[i]);
}
return createType(aClass, createSubstitutor(map));
}
private static class TypeDetacher extends PsiTypeVisitor<PsiType> {
public static final TypeDetacher INSTANCE = new TypeDetacher();
public PsiType visitType(PsiType type) {
return type;
}
public PsiType visitWildcardType(PsiWildcardType wildcardType) {
final PsiType bound = wildcardType.getBound();
if (bound == null) {
return wildcardType;
}
else {
return PsiWildcardType.changeBound(wildcardType, bound.accept(this));
}
}
public PsiType visitArrayType(PsiArrayType arrayType) {
final PsiType componentType = arrayType.getComponentType();
final PsiType detachedComponentType = componentType.accept(this);
if (detachedComponentType == componentType) return arrayType; // optimization
return detachedComponentType.createArrayType();
}
public PsiType visitClassType(PsiClassType classType) {
final PsiClassType.ClassResolveResult resolveResult = classType.resolveGenerics();
final PsiClass aClass = resolveResult.getElement();
if (aClass == null) return classType;
final HashMap<PsiTypeParameter, PsiType> map = new HashMap<PsiTypeParameter, PsiType>();
for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(aClass)) {
PsiType type = resolveResult.getSubstitutor().substitute(parameter);
if (type != null) {
type = type.accept(this);
}
map.put(parameter, type);
}
return new PsiImmediateClassType(aClass, PsiSubstitutorImpl.createSubstitutor(map));
}
}
@NotNull
public PsiType detachType(@NotNull PsiType type) {
return type.accept(TypeDetacher.INSTANCE);
public PsiType detachType(@NotNull final PsiType type) {
return type;
}
@NotNull
public PsiSubstitutor createRawSubstitutor(@NotNull PsiTypeParameterListOwner owner) {
Map<PsiTypeParameter, PsiType> substMap = null;
public PsiSubstitutor createRawSubstitutor(@NotNull final PsiTypeParameterListOwner owner) {
Map<PsiTypeParameter, PsiType> substitutorMap = null;
for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(owner)) {
if (substMap == null) substMap = new HashMap<PsiTypeParameter, PsiType>();
substMap.put(parameter, null);
if (substitutorMap == null) substitutorMap = new HashMap<PsiTypeParameter, PsiType>();
substitutorMap.put(parameter, null);
}
return PsiSubstitutorImpl.createSubstitutor(substMap);
}
@NotNull
public PsiSubstitutor createRawSubstitutor(@NotNull PsiSubstitutor baseSubstitutor, @NotNull PsiTypeParameter[] typeParameters) {
Map<PsiTypeParameter, PsiType> substMap = null;
for (PsiTypeParameter parameter : typeParameters) {
if (substMap == null) substMap = new HashMap<PsiTypeParameter, PsiType>();
substMap.put(parameter, null);
}
return baseSubstitutor.putAll(PsiSubstitutorImpl.createSubstitutor(substMap));
return PsiSubstitutorImpl.createSubstitutor(substitutorMap);
}
@NotNull
public PsiElement createDummyHolder(@NotNull String text, @NotNull IElementType type, @Nullable PsiElement context) {
public PsiSubstitutor createRawSubstitutor(@NotNull final PsiSubstitutor baseSubstitutor, @NotNull final PsiTypeParameter[] typeParameters) {
Map<PsiTypeParameter, PsiType> substitutorMap = null;
for (PsiTypeParameter parameter : typeParameters) {
if (substitutorMap == null) substitutorMap = new HashMap<PsiTypeParameter, PsiType>();
substitutorMap.put(parameter, null);
}
return baseSubstitutor.putAll(PsiSubstitutorImpl.createSubstitutor(substitutorMap));
}
@NotNull
public PsiElement createDummyHolder(@NotNull final String text, @NotNull final IElementType type, @Nullable final PsiElement context) {
final DummyHolder result = DummyHolderFactory.createHolder(myManager, context);
final FileElement holder = result.getTreeElement();
final Language language = type.getLanguage();
final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(language);
if (parserDefinition == null) {
throw new AssertionError("No parser definition for language " + language);
}
assert parserDefinition != null : "No parser definition for language " + language;
final Project project = myManager.getProject();
final Lexer lexer = parserDefinition.createLexer(project);
final PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(project, holder, lexer, language, text);
final ASTNode node = parserDefinition.createParser(project).parse(type, builder);
holder.rawAddChildren((TreeElement)node);
return node.getPsi();
final PsiElement psi = node.getPsi();
assert psi != null : text;
return psi;
}
@NotNull
public PsiSubstitutor createSubstitutor(@NotNull Map<PsiTypeParameter, PsiType> map) {
public PsiSubstitutor createSubstitutor(@NotNull final Map<PsiTypeParameter, PsiType> map) {
return PsiSubstitutorImpl.createSubstitutor(map);
}
@Nullable
public PsiPrimitiveType createPrimitiveType(@NotNull String text) {
return getPrimitiveType(text);
}
public static PsiPrimitiveType getPrimitiveType(final String text) {
return ourPrimitiveTypesMap.get(text);
public PsiPrimitiveType createPrimitiveType(@NotNull final String text) {
return PsiJavaParserFacadeImpl.getPrimitiveType(text);
}
@NotNull
public PsiClassType createTypeByFQClassName(@NotNull String qName) {
public PsiClassType createTypeByFQClassName(@NotNull final String qName) {
return createTypeByFQClassName(qName, GlobalSearchScope.allScope(myManager.getProject()));
}
@NotNull
public PsiClassType createTypeByFQClassName(@NotNull String qName, @NotNull GlobalSearchScope resolveScope) {
public PsiClassType createTypeByFQClassName(@NotNull final String qName, @NotNull final GlobalSearchScope resolveScope) {
return new PsiClassReferenceType(createReferenceElementByFQClassName(qName, resolveScope), null);
}
@NotNull
public PsiJavaCodeReferenceElement createClassReferenceElement(@NotNull PsiClass aClass) {
public PsiJavaCodeReferenceElement createClassReferenceElement(@NotNull final PsiClass aClass) {
final String text;
if (aClass instanceof PsiAnonymousClass) {
text = ((PsiAnonymousClass)aClass).getBaseClassType().getPresentableText();
@@ -421,19 +326,20 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
}
@NotNull
public PsiJavaCodeReferenceElement createReferenceElementByFQClassName(@NotNull String qName, @NotNull GlobalSearchScope resolveScope) {
String shortName = PsiNameHelper.getShortClassName(qName);
public PsiJavaCodeReferenceElement createReferenceElementByFQClassName(@NotNull final String qName,
@NotNull final GlobalSearchScope resolveScope) {
final String shortName = PsiNameHelper.getShortClassName(qName);
return new LightClassReference(myManager, shortName, qName, resolveScope);
}
@NotNull
public PsiJavaCodeReferenceElement createFQClassNameReferenceElement(@NotNull String qName, @NotNull GlobalSearchScope resolveScope) {
public PsiJavaCodeReferenceElement createFQClassNameReferenceElement(@NotNull final String qName,
@NotNull final GlobalSearchScope resolveScope) {
return new LightClassReference(myManager, qName, qName, resolveScope);
}
@NotNull
public PsiJavaCodeReferenceElement createPackageReferenceElement(@NotNull PsiPackage aPackage)
throws IncorrectOperationException {
public PsiJavaCodeReferenceElement createPackageReferenceElement(@NotNull final PsiPackage aPackage) throws IncorrectOperationException {
if (aPackage.getQualifiedName().length() == 0) {
throw new IncorrectOperationException("Cannot create reference to default package.");
}
@@ -441,18 +347,20 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
}
@NotNull
public PsiPackageStatement createPackageStatement(@NotNull String name) throws IncorrectOperationException {
final PsiJavaFile javaFile = (PsiJavaFile)PsiFileFactory.getInstance(myManager.getProject()).createFileFromText("dummy.java", "package " + name + ";");
final PsiPackageStatement stmt = javaFile.getPackageStatement();
if (stmt == null) throw new IncorrectOperationException("Incorrect package name: " + name);
public PsiPackageStatement createPackageStatement(@NotNull final String name) throws IncorrectOperationException {
final PsiJavaFile aFile = createDummyJavaFile(join("package ", name, ";"));
final PsiPackageStatement stmt = aFile.getPackageStatement();
if (stmt == null) {
throw new IncorrectOperationException("Incorrect package name: " + name);
}
return stmt;
}
@NotNull
public PsiJavaCodeReferenceCodeFragment createReferenceCodeFragment(@NotNull String text,
PsiElement context,
boolean isPhysical,
boolean isClassesAccepted) {
public PsiJavaCodeReferenceCodeFragment createReferenceCodeFragment(@NotNull final String text,
final PsiElement context,
final boolean isPhysical,
final boolean isClassesAccepted) {
final PsiJavaCodeReferenceCodeFragmentImpl result =
new PsiJavaCodeReferenceCodeFragmentImpl(myManager.getProject(), isPhysical, "fragment.java", text, isClassesAccepted);
result.setContext(context);
@@ -460,51 +368,54 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
}
@NotNull
public PsiImportStaticStatement createImportStaticStatement(@NotNull PsiClass aClass, @NotNull String memberName) throws IncorrectOperationException {
public PsiImportStaticStatement createImportStaticStatement(@NotNull final PsiClass aClass,
@NotNull final String memberName) throws IncorrectOperationException {
if (aClass instanceof PsiAnonymousClass) {
throw new IncorrectOperationException("Cannot create import statement for anonymous class.");
}
else if (aClass.getParent() instanceof PsiDeclarationStatement) {
throw new IncorrectOperationException("Cannot create import statement for local class.");
}
@NonNls String text = "import static " + aClass.getQualifiedName() + "." + memberName + ";";
PsiJavaFile aFile = createDummyJavaFile(text);
PsiImportStaticStatement statement = aFile.getImportList().getImportStaticStatements()[0];
final PsiJavaFile aFile = createDummyJavaFile(join("import static ", aClass.getQualifiedName(), ".", memberName, ";"));
final PsiImportStatementBase statement = extractImport(aFile, true);
return (PsiImportStaticStatement)CodeStyleManager.getInstance(myManager.getProject()).reformat(statement);
}
@NotNull
public PsiParameterList createParameterList(@NotNull String[] names, @NotNull PsiType[] types) throws IncorrectOperationException {
@NonNls String text = "void method(";
String sep = "";
for (int i = 0; i < names.length; i++) {
final String name = names[i];
PsiType type = types[i];
text += sep + type.getCanonicalText() + " " + name;
sep = ",";
public PsiParameterList createParameterList(@NotNull final String[] names, @NotNull final PsiType[] types) throws IncorrectOperationException {
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append("void method(");
for (int i = 0; i < names.length; i++) {
if (i > 0) builder.append(", ");
builder.append(types[i].getCanonicalText()).append(' ').append(names[i]);
}
return createMethodFromText(builder.toString(), null).getParameterList();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
text += "){}";
PsiMethod method = createMethodFromText(text, null);
return method.getParameterList();
}
@NotNull
public PsiReferenceList createReferenceList(@NotNull PsiJavaCodeReferenceElement[] references) throws IncorrectOperationException {
@NonNls String text = "void method() ";
if (references.length > 0) text += "throws ";
String sep = "";
for (final PsiJavaCodeReferenceElement reference : references) {
text += sep + reference.getCanonicalText();
sep = ",";
public PsiReferenceList createReferenceList(@NotNull final PsiJavaCodeReferenceElement[] references) throws IncorrectOperationException {
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append("void method() throws ");
for (int i = 0; i < references.length; i++) {
if (i > 0) builder.append(", ");
builder.append(references[i].getCanonicalText());
}
return createMethodFromText(builder.toString(), null).getThrowsList();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
text += "{}";
PsiMethod method = createMethodFromText(text, null);
return method.getThrowsList();
}
@NotNull
public PsiJavaCodeReferenceElement createPackageReferenceElement(@NotNull String packageName)
throws IncorrectOperationException {
public PsiJavaCodeReferenceElement createPackageReferenceElement(@NotNull final String packageName) throws IncorrectOperationException {
if (packageName.length() == 0) {
throw new IncorrectOperationException("Cannot create reference to default package.");
}
@@ -512,8 +423,8 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
}
@NotNull
public PsiReferenceExpression createReferenceExpression(@NotNull PsiClass aClass) throws IncorrectOperationException {
String text;
public PsiReferenceExpression createReferenceExpression(@NotNull final PsiClass aClass) throws IncorrectOperationException {
final String text;
if (aClass instanceof PsiAnonymousClass) {
text = ((PsiAnonymousClass)aClass).getBaseClassType().getPresentableText();
}
@@ -524,7 +435,7 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
}
@NotNull
public PsiReferenceExpression createReferenceExpression(@NotNull PsiPackage aPackage) throws IncorrectOperationException {
public PsiReferenceExpression createReferenceExpression(@NotNull final PsiPackage aPackage) throws IncorrectOperationException {
if (aPackage.getQualifiedName().length() == 0) {
throw new IncorrectOperationException("Cannot create reference to default package.");
}
@@ -532,13 +443,13 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
}
@NotNull
public PsiIdentifier createIdentifier(@NotNull String text) throws IncorrectOperationException {
public PsiIdentifier createIdentifier(@NotNull final String text) throws IncorrectOperationException {
PsiUtil.checkIsIdentifier(myManager, text);
return new LightIdentifier(myManager, text);
}
@NotNull
public PsiKeyword createKeyword(@NotNull String text) throws IncorrectOperationException {
public PsiKeyword createKeyword(@NotNull final String text) throws IncorrectOperationException {
if (!JavaPsiFacade.getInstance(myManager.getProject()).getNameHelper().isKeyword(text)) {
throw new IncorrectOperationException("\"" + text + "\" is not a keyword.");
}
@@ -546,21 +457,21 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
}
@NotNull
public PsiImportStatement createImportStatement(@NotNull PsiClass aClass) throws IncorrectOperationException {
public PsiImportStatement createImportStatement(@NotNull final PsiClass aClass) throws IncorrectOperationException {
if (aClass instanceof PsiAnonymousClass) {
throw new IncorrectOperationException("Cannot create import statement for anonymous class.");
}
else if (aClass.getParent() instanceof PsiDeclarationStatement) {
throw new IncorrectOperationException("Cannot create import statement for local class.");
}
@NonNls String text = "import " + aClass.getQualifiedName() + ";";
PsiJavaFile aFile = createDummyJavaFile(text);
PsiImportStatement statement = aFile.getImportList().getImportStatements()[0];
final PsiJavaFile aFile = createDummyJavaFile(join("import ", aClass.getQualifiedName(), ";"));
final PsiImportStatementBase statement = extractImport(aFile, false);
return (PsiImportStatement)CodeStyleManager.getInstance(myManager.getProject()).reformat(statement);
}
@NotNull
public PsiImportStatement createImportStatementOnDemand(@NotNull String packageName) throws IncorrectOperationException {
public PsiImportStatement createImportStatementOnDemand(@NotNull final String packageName) throws IncorrectOperationException {
if (packageName.length() == 0) {
throw new IncorrectOperationException("Cannot create import statement for default package.");
}
@@ -568,102 +479,103 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
throw new IncorrectOperationException("Incorrect package name: \"" + packageName + "\".");
}
@NonNls String text = "import " + packageName + ".*;";
PsiJavaFile aFile = createDummyJavaFile(text);
PsiImportStatement statement = aFile.getImportList().getImportStatements()[0];
final PsiJavaFile aFile = createDummyJavaFile(join("import ", packageName, ".*;"));
final PsiImportStatementBase statement = extractImport(aFile, false);
return (PsiImportStatement)CodeStyleManager.getInstance(myManager.getProject()).reformat(statement);
}
@NotNull
public PsiDeclarationStatement createVariableDeclarationStatement(@NotNull String name, @NotNull PsiType type, PsiExpression initializer)
throws IncorrectOperationException {
public PsiDeclarationStatement createVariableDeclarationStatement(@NotNull final String name,
@NotNull final PsiType type,
final PsiExpression initializer) throws IncorrectOperationException {
if (!JavaPsiFacade.getInstance(myManager.getProject()).getNameHelper().isIdentifier(name)) {
throw new IncorrectOperationException("\"" + name + "\" is not an identifier.");
}
if (PsiType.NULL.equals(type)) {
throw new IncorrectOperationException("Cannot create field with type \"<null_type>\".");
throw new IncorrectOperationException("Cannot create variable with type \"null\".");
}
@NonNls StringBuilder buffer = new StringBuilder();
buffer.append("X ");
buffer.append(name);
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
builder.append("X ").append(name);
if (initializer != null) {
buffer.append("=x");
builder.append(" = x");
}
buffer.append(";");
PsiDeclarationStatement statement = (PsiDeclarationStatement)createStatementFromText(buffer.toString(), null);
PsiVariable variable = (PsiVariable)statement.getDeclaredElements()[0];
variable.getTypeElement().replace(createTypeElement(type));
PsiUtil.setModifierProperty(variable, PsiModifier.FINAL, CodeStyleSettingsManager.getSettings(myManager.getProject()).GENERATE_FINAL_LOCALS);
builder.append(';');
final String text = builder.toString();
StringBuilderSpinAllocator.dispose(builder);
final PsiDeclarationStatement statement = (PsiDeclarationStatement)createStatementFromText(text, null);
final PsiVariable variable = (PsiVariable)statement.getDeclaredElements()[0];
replace(variable.getTypeElement(), createTypeElement(type), text);
PsiUtil.setModifierProperty(variable, PsiModifier.FINAL,
CodeStyleSettingsManager.getSettings(myManager.getProject()).GENERATE_FINAL_LOCALS);
if (initializer != null) {
variable.getInitializer().replace(initializer);
replace(variable.getInitializer(), initializer, text);
}
markGenerated(statement);
return statement;
}
@NotNull
public PsiDocTag createParamTag(@NotNull String parameterName, @NonNls String description) throws IncorrectOperationException {
@NonNls StringBuilder buffer = new StringBuilder();
buffer.append(" * @param ");
buffer.append(parameterName);
buffer.append(" ");
final String[] strings = description.split("\\n");
for (int i = 0; i < strings.length; i++) {
String string = strings[i];
if (i > 0) buffer.append("\n * ");
buffer.append(string);
public PsiDocTag createParamTag(@NotNull final String parameterName, @NonNls final String description) throws IncorrectOperationException {
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append(" * @param ");
builder.append(parameterName);
builder.append(" ");
final String[] strings = description.split("\\n");
for (int i = 0; i < strings.length; i++) {
if (i > 0) builder.append("\n * ");
builder.append(strings[i]);
}
return createDocTagFromText(builder.toString());
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
return createDocTagFromText(buffer.toString(), null);
}
@NotNull
public PsiExpressionCodeFragment createExpressionCodeFragment(@NotNull String text,
PsiElement context,
public PsiExpressionCodeFragment createExpressionCodeFragment(@NotNull final String text,
final PsiElement context,
final PsiType expectedType,
boolean isPhysical) {
final PsiExpressionCodeFragmentImpl result = new PsiExpressionCodeFragmentImpl(
myManager.getProject(), isPhysical, "fragment.java", text, expectedType);
final boolean isPhysical) {
final PsiExpressionCodeFragmentImpl result =
new PsiExpressionCodeFragmentImpl(myManager.getProject(), isPhysical, "fragment.java", text, expectedType);
result.setContext(context);
return result;
}
@NotNull
public JavaCodeFragment createCodeBlockCodeFragment(@NotNull String text, PsiElement context, boolean isPhysical) {
final PsiCodeFragmentImpl result = new PsiCodeFragmentImpl(myManager.getProject(), JavaElementType.STATEMENTS,
isPhysical,
"fragment.java",
text);
public JavaCodeFragment createCodeBlockCodeFragment(@NotNull final String text, final PsiElement context, final boolean isPhysical) {
final PsiCodeFragmentImpl result =
new PsiCodeFragmentImpl(myManager.getProject(), JavaElementType.STATEMENTS, isPhysical, "fragment.java", text);
result.setContext(context);
return result;
}
@NotNull
public PsiTypeCodeFragment createTypeCodeFragment(@NotNull String text, PsiElement context, boolean isPhysical) {
public PsiTypeCodeFragment createTypeCodeFragment(@NotNull final String text, final PsiElement context, final boolean isPhysical) {
return createTypeCodeFragment(text, context, false, isPhysical, false);
}
@NotNull
public PsiTypeCodeFragment createTypeCodeFragment(@NotNull String text,
PsiElement context,
boolean isVoidValid,
boolean isPhysical) {
public PsiTypeCodeFragment createTypeCodeFragment(@NotNull final String text,
final PsiElement context,
final boolean isVoidValid,
final boolean isPhysical) {
return createTypeCodeFragment(text, context, true, isPhysical, false);
}
@NotNull
public PsiTypeCodeFragment createTypeCodeFragment(@NotNull String text,
PsiElement context,
boolean isVoidValid,
boolean isPhysical,
boolean allowEllipsis) {
final PsiTypeCodeFragmentImpl result = new PsiTypeCodeFragmentImpl(myManager.getProject(),
isPhysical,
allowEllipsis,
"fragment.java",
text);
public PsiTypeCodeFragment createTypeCodeFragment(@NotNull final String text,
final PsiElement context,
final boolean isVoidValid,
final boolean isPhysical,
final boolean allowEllipsis) {
final PsiTypeCodeFragmentImpl result
= new PsiTypeCodeFragmentImpl(myManager.getProject(), isPhysical, allowEllipsis, "fragment.java", text);
result.setContext(context);
if (isVoidValid) {
result.putUserData(PsiUtil.VALID_VOID_TYPE_IN_CODE_FRAGMENT, Boolean.TRUE);
@@ -671,7 +583,6 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
return result;
}
@NotNull
public PsiAnnotation createAnnotationFromText(@NotNull final String annotationText, final PsiElement context) throws IncorrectOperationException {
final PsiAnnotation psiAnnotation = super.createAnnotationFromText(annotationText, context);
@@ -727,8 +638,8 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
}
@NotNull
public PsiTypeParameter createTypeParameterFromText(@NotNull final String text, final PsiElement context) throws
IncorrectOperationException {
public PsiTypeParameter createTypeParameterFromText(@NotNull final String text,
final PsiElement context) throws IncorrectOperationException {
final PsiTypeParameter typeParameter = super.createTypeParameterFromText(text, context);
markGenerated(typeParameter);
return typeParameter;
@@ -742,18 +653,18 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
}
@NotNull
public PsiMethod createMethodFromText(@NotNull final String text, final PsiElement context, final LanguageLevel level) throws
IncorrectOperationException {
public PsiMethod createMethodFromText(@NotNull final String text,
final PsiElement context,
final LanguageLevel level) throws IncorrectOperationException {
final PsiMethod method = super.createMethodFromText(text, context, level);
markGenerated(method);
return method;
}
@NotNull
public PsiCatchSection createCatchSection(@NotNull final PsiClassType exceptionType,
@NotNull final String exceptionName, final PsiElement context) throws
IncorrectOperationException {
@NotNull final String exceptionName,
final PsiElement context) throws IncorrectOperationException {
final PsiCatchSection psiCatchSection = super.createCatchSection(exceptionType, exceptionName, context);
markGenerated(psiCatchSection);
return psiCatchSection;
@@ -762,4 +673,25 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
private static void markGenerated(final PsiElement element) {
((TreeElement)element.getNode()).acceptTree(new GeneratedMarkerVisitor());
}
private static PsiImportStatementBase extractImport(final PsiJavaFile aFile, final boolean isStatic) {
final PsiImportList importList = aFile.getImportList();
assert importList != null : aFile;
final PsiImportStatementBase[] statements = isStatic ? importList.getImportStaticStatements() : importList.getImportStatements();
assert statements.length == 1 : aFile.getText();
return statements[0];
}
private static void replace(final PsiElement original, final PsiElement replacement, final String message) {
assert original != null : message;
original.replace(replacement);
}
/**
* @deprecated use {@link PsiJavaParserFacadeImpl#getPrimitiveType(String)} (remove in IDEA 11).
*/
@SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
public static PsiPrimitiveType getPrimitiveType(final String text) {
return PsiJavaParserFacadeImpl.getPrimitiveType(text);
}
}
@@ -14,14 +14,13 @@
* limitations under the License.
*/
/*
* @author max
*/
package com.intellij.psi.impl;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.fileTemplates.JavaTemplateUtil;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.java.parser.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.StdFileTypes;
@@ -29,79 +28,154 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.DummyHolder;
import com.intellij.psi.impl.source.DummyHolderFactory;
import com.intellij.psi.impl.source.JavaDummyElement;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.parsing.DeclarationParsing;
import com.intellij.psi.impl.source.parsing.ExpressionParsing;
import com.intellij.psi.impl.source.parsing.JavaParsingContext;
import com.intellij.psi.impl.source.parsing.Parsing;
import com.intellij.psi.impl.source.tree.CompositeElement;
import com.intellij.psi.impl.source.tree.FileElement;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
import java.util.Properties;
import static com.intellij.openapi.util.text.StringUtil.join;
/*
* @author max
*/
public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJavaParserFacade {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiJavaParserFacadeImpl");
protected static final Map<String, PsiPrimitiveType> ourPrimitiveTypesMap = new HashMap<String, PsiPrimitiveType>();
protected PsiJavaFile myDummyJavaFile;
private static final JavaParserUtil.ParserWrapper ANNOTATION = new JavaParserUtil.ParserWrapper() {
@Override
public void parse(final PsiBuilder builder) {
DeclarationParser.parseAnnotation(builder);
}
};
public PsiJavaParserFacadeImpl(PsiManagerEx manager) {
private static final JavaParserUtil.ParserWrapper PARAMETER = new JavaParserUtil.ParserWrapper() {
@Override
public void parse(final PsiBuilder builder) {
DeclarationParser.parseParameter(builder, true);
}
};
private static final JavaParserUtil.ParserWrapper TYPE = new JavaParserUtil.ParserWrapper() {
@Override
public void parse(final PsiBuilder builder) {
ReferenceParser.parseType(builder, ReferenceParser.EAT_LAST_DOT | ReferenceParser.ELLIPSIS | ReferenceParser.WILDCARD);
}
};
private static final JavaParserUtil.ParserWrapper TYPE_PARAMETER = new JavaParserUtil.ParserWrapper() {
@Override
public void parse(final PsiBuilder builder) {
ReferenceParser.parseTypeParameter(builder);
}
};
private static final JavaParserUtil.ParserWrapper DECLARATION = new JavaParserUtil.ParserWrapper() {
@Override
public void parse(final PsiBuilder builder) {
DeclarationParser.parse(builder, DeclarationParser.Context.CLASS);
}
};
private static final JavaParserUtil.ParserWrapper CODE_BLOCK = new JavaParserUtil.ParserWrapper() {
@Override
public void parse(final PsiBuilder builder) {
StatementParser.parseCodeBlockDeep(builder, true);
}
};
private static final JavaParserUtil.ParserWrapper STATEMENT = new JavaParserUtil.ParserWrapper() {
@Override
public void parse(final PsiBuilder builder) {
StatementParser.parseStatement(builder);
}
};
private static final JavaParserUtil.ParserWrapper EXPRESSION = new JavaParserUtil.ParserWrapper() {
@Override
public void parse(final PsiBuilder builder) {
ExpressionParser.parse(builder);
}
};
private static final JavaParserUtil.ParserWrapper ENUM_CONSTANT = new JavaParserUtil.ParserWrapper() {
@Override
public void parse(final PsiBuilder builder) {
DeclarationParser.parseEnumConstant(builder);
}
};
private static final JavaParserUtil.ParserWrapper CATCH_SECTION = new JavaParserUtil.ParserWrapper() {
@Override
public void parse(final PsiBuilder builder) {
StatementParser.parseCatchBlock(builder);
}
};
private static final Map<String, PsiPrimitiveType> PRIMITIVE_TYPES;
static {
PRIMITIVE_TYPES = new HashMap<String, PsiPrimitiveType>();
PRIMITIVE_TYPES.put(PsiType.BYTE.getCanonicalText(), PsiType.BYTE);
PRIMITIVE_TYPES.put(PsiType.CHAR.getCanonicalText(), PsiType.CHAR);
PRIMITIVE_TYPES.put(PsiType.DOUBLE.getCanonicalText(), PsiType.DOUBLE);
PRIMITIVE_TYPES.put(PsiType.FLOAT.getCanonicalText(), PsiType.FLOAT);
PRIMITIVE_TYPES.put(PsiType.INT.getCanonicalText(), PsiType.INT);
PRIMITIVE_TYPES.put(PsiType.LONG.getCanonicalText(), PsiType.LONG);
PRIMITIVE_TYPES.put(PsiType.SHORT.getCanonicalText(), PsiType.SHORT);
PRIMITIVE_TYPES.put(PsiType.BOOLEAN.getCanonicalText(), PsiType.BOOLEAN);
PRIMITIVE_TYPES.put(PsiType.VOID.getCanonicalText(), PsiType.VOID);
PRIMITIVE_TYPES.put(PsiType.NULL.getCanonicalText(), PsiType.NULL);
}
public PsiJavaParserFacadeImpl(final PsiManagerEx manager) {
super(manager);
}
@NotNull
public PsiAnnotation createAnnotationFromText(@NotNull String annotationText, PsiElement context) throws IncorrectOperationException {
final FileElement holderElement = DummyHolderFactory.createHolder(myManager, context).getTreeElement();
CompositeElement annotationElement = getJavaParsingContext(holderElement).getDeclarationParsing().parseAnnotationFromText(myManager, annotationText, getLanguageLevel(context));
if (annotationElement == null || annotationElement.getElementType() != JavaElementType.ANNOTATION) {
throw new IncorrectOperationException("Incorrect annotation \"" + annotationText + "\".");
public PsiAnnotation createAnnotationFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, ANNOTATION, false), context);
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
if (!(element instanceof PsiAnnotation)) {
throw new IncorrectOperationException("Incorrect annotation \"" + text + "\".");
}
holderElement.rawAddChildren(annotationElement);
return (PsiAnnotation)SourceTreeToPsiMap.treeElementToPsi(annotationElement);
}
private LanguageLevel getLanguageLevel(final PsiElement context) {
if (context == null) {
return LanguageLevelProjectExtension.getInstance(myManager.getProject()).getLanguageLevel();
}
return PsiUtil.getLanguageLevel(context);
return (PsiAnnotation)element;
}
@NotNull
public PsiDocTag createDocTagFromText(@NotNull String docTagText, PsiElement context) throws IncorrectOperationException {
StringBuilder buffer = new StringBuilder();
buffer.append("/**\n");
buffer.append(docTagText);
buffer.append("\n */");
PsiDocComment comment = createDocCommentFromText(buffer.toString(), context);
return comment.getTags()[0];
public PsiDocTag createDocTagFromText(@NotNull final String text) throws IncorrectOperationException {
return createDocCommentFromText(join("/**\n", text, "\n */")).getTags()[0];
}
@NotNull
public PsiDocComment createDocCommentFromText(@NotNull String docCommentText, PsiElement context) throws IncorrectOperationException {
@NonNls StringBuilder buffer = new StringBuilder();
buffer.append(docCommentText);
buffer.append("void m();");
final PsiMethod method = createMethodFromText(buffer.toString(), null);
return method.getDocComment();
public PsiDocTag createDocTagFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
return createDocTagFromText(text);
}
@NotNull
public PsiClass createClassFromText(@NotNull String body, PsiElement context) throws IncorrectOperationException {
@NonNls String fileText = "class _Dummy_ { " + body + " }";
PsiJavaFile aFile = createDummyJavaFile(fileText);
PsiClass[] classes = aFile.getClasses();
public PsiDocComment createDocCommentFromText(@NotNull final String text) throws IncorrectOperationException {
final PsiMethod method = createMethodFromText(join(text, "void m();"), null);
final PsiDocComment comment = method.getDocComment();
assert comment != null : text;
return comment;
}
@NotNull
public PsiDocComment createDocCommentFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
return createDocCommentFromText(text);
}
@NotNull
public PsiClass createClassFromText(@NotNull final String body, final PsiElement context) throws IncorrectOperationException {
final PsiJavaFile aFile = createDummyJavaFile(join("class _Dummy_ { ", body, " }"));
final PsiClass[] classes = aFile.getClasses();
if (classes.length != 1) {
throw new IncorrectOperationException("Incorrect class \"" + body + "\".");
}
@@ -109,211 +183,186 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
}
@NotNull
public PsiField createFieldFromText(@NotNull String text, PsiElement context) throws IncorrectOperationException {
final FileElement holderElement = DummyHolderFactory.createHolder(myManager, context).getTreeElement();
TreeElement decl = getJavaParsingContext(holderElement).getDeclarationParsing().parseDeclarationText(myManager, LanguageLevelProjectExtension
.getInstance(myManager.getProject()).getLanguageLevel(), text, DeclarationParsing.Context.CLASS_CONTEXT);
if (decl == null || decl.getElementType() != JavaElementType.FIELD) {
public PsiField createFieldFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, DECLARATION, false), context);
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
if (!(element instanceof PsiField)) {
throw new IncorrectOperationException("Incorrect field \"" + text + "\".");
}
holderElement.rawAddChildren(decl);
return (PsiField)SourceTreeToPsiMap.treeElementToPsi(decl);
}
protected JavaParsingContext getJavaParsingContext (FileElement holderElement) {
return new JavaParsingContext(holderElement.getCharTable(), LanguageLevelProjectExtension.getInstance(myManager.getProject()).getLanguageLevel());
}
private static JavaParsingContext getJavaParsingContext (FileElement holderElement, LanguageLevel languageLevel) {
return new JavaParsingContext(holderElement.getCharTable(), languageLevel);
return (PsiField)element;
}
@NotNull
public PsiMethod createMethodFromText(@NotNull String text, PsiElement context, LanguageLevel level) throws IncorrectOperationException {
final FileElement holderElement = DummyHolderFactory.createHolder(myManager, context).getTreeElement();
TreeElement decl = getJavaParsingContext(holderElement, level).getDeclarationParsing().parseDeclarationText(myManager, level, text,
DeclarationParsing.Context.CLASS_CONTEXT);
if (decl == null || decl.getElementType() != JavaElementType.METHOD) {
throw new IncorrectOperationException("Incorrect method '" + text + "'. Context:"+context+"; Level:"+level+"; parsed: "+(decl == null ? null : DebugUtil.treeToString(decl, false)));
public PsiMethod createMethodFromText(@NotNull final String text, final PsiElement context, final LanguageLevel level)
throws IncorrectOperationException {
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, DECLARATION, false, level), context);
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
if (!(element instanceof PsiMethod)) {
throw new IncorrectOperationException("Incorrect method \"" + text + "\".");
}
holderElement.rawAddChildren(decl);
return (PsiMethod)SourceTreeToPsiMap.treeElementToPsi(decl);
return (PsiMethod)element;
}
@NotNull
public final PsiMethod createMethodFromText(@NotNull String text, PsiElement context) throws IncorrectOperationException {
return createMethodFromText(text, context, LanguageLevelProjectExtension.getInstance(myManager.getProject()).getLanguageLevel());
public final PsiMethod createMethodFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
final LanguageLevel level = LanguageLevelProjectExtension.getInstance(myManager.getProject()).getLanguageLevel();
return createMethodFromText(text, context, level);
}
@NotNull
public PsiParameter createParameterFromText(@NotNull String text, PsiElement context) throws IncorrectOperationException {
final FileElement holderElement = DummyHolderFactory.createHolder(myManager, context).getTreeElement();
CompositeElement param = getJavaParsingContext(holderElement).getDeclarationParsing().parseParameterText(text);
if (param == null) {
public PsiParameter createParameterFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, PARAMETER, false), context);
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
if (!(element instanceof PsiParameter)) {
throw new IncorrectOperationException("Incorrect parameter \"" + text + "\".");
}
holderElement.rawAddChildren(param);
return (PsiParameter)SourceTreeToPsiMap.treeElementToPsi(param);
return (PsiParameter)element;
}
@NotNull
public PsiType createTypeFromText(@NotNull String text, PsiElement context) throws IncorrectOperationException {
public PsiType createTypeFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
return createTypeInner(text, context, false);
}
protected PsiType createTypeInner(final String text, final PsiElement context, boolean markAsCopy) throws IncorrectOperationException {
PsiPrimitiveType primitiveType = ourPrimitiveTypesMap.get(text);
protected PsiType createTypeInner(final String text, final PsiElement context, final boolean markAsCopy) throws IncorrectOperationException {
final PsiPrimitiveType primitiveType = PRIMITIVE_TYPES.get(text);
if (primitiveType != null) return primitiveType;
final FileElement holderElement = DummyHolderFactory.createHolder(myManager, context).getTreeElement();
CompositeElement typeElement = Parsing.parseTypeText(myManager, text, 0, text.length(), holderElement.getCharTable());
if (typeElement == null) {
throw new IncorrectOperationException("Incorrect type \"" + text + "\"");
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, TYPE, false), context);
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
if (!(element instanceof PsiTypeElement)) {
throw new IncorrectOperationException("Incorrect type \"" + text + "\".");
}
holderElement.rawAddChildren(typeElement);
if (markAsCopy) {
holderElement.acceptTree(new GeneratedMarkerVisitor());
holder.getTreeElement().acceptTree(new GeneratedMarkerVisitor());
}
PsiTypeElement psiTypeElement = (PsiTypeElement)SourceTreeToPsiMap.treeElementToPsi(typeElement);
if (psiTypeElement == null) {
throw new IncorrectOperationException("PSI is null for element "+typeElement);
}
return psiTypeElement.getType();
return ((PsiTypeElement)element).getType();
}
@NotNull
public PsiCodeBlock createCodeBlockFromText(@NotNull String text, PsiElement context) throws IncorrectOperationException {
final FileElement holderElement = DummyHolderFactory.createHolder(myManager, context).getTreeElement();
CompositeElement treeElement = getJavaParsingContext(holderElement).getStatementParsing().parseCodeBlockText(myManager, text);
if (treeElement == null) {
public PsiCodeBlock createCodeBlockFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, CODE_BLOCK, true), context);
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
if (!(element instanceof PsiCodeBlock)) {
throw new IncorrectOperationException("Incorrect code block \"" + text + "\".");
}
holderElement.rawAddChildren(treeElement);
return (PsiCodeBlock)SourceTreeToPsiMap.treeElementToPsi(treeElement);
return (PsiCodeBlock)element;
}
@NotNull
public PsiStatement createStatementFromText(@NotNull String text, PsiElement context) throws IncorrectOperationException {
final FileElement treeHolder = DummyHolderFactory.createHolder(myManager, context).getTreeElement();
TreeElement treeElement = getJavaParsingContext(treeHolder).getStatementParsing().parseStatementText(text);
if (treeElement == null) {
public PsiStatement createStatementFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, STATEMENT, false), context);
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
if (!(element instanceof PsiStatement)) {
throw new IncorrectOperationException("Incorrect statement \"" + text + "\".");
}
treeHolder.rawAddChildren(treeElement);
return (PsiStatement)SourceTreeToPsiMap.treeElementToPsi(treeElement);
return (PsiStatement)element;
}
@NotNull
public PsiExpression createExpressionFromText(@NotNull String text, PsiElement context) throws IncorrectOperationException {
final FileElement treeHolder = DummyHolderFactory.createHolder(myManager, context).getTreeElement();
final CompositeElement treeElement = ExpressionParsing.parseExpressionText(myManager, text, 0,
text.length(), treeHolder.getCharTable());
if (treeElement == null) {
public PsiExpression createExpressionFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, EXPRESSION, false), context);
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
if (!(element instanceof PsiExpression)) {
throw new IncorrectOperationException("Incorrect expression \"" + text + "\".");
}
treeHolder.rawAddChildren(treeElement);
return (PsiExpression)SourceTreeToPsiMap.treeElementToPsi(treeElement);
return (PsiExpression)element;
}
protected PsiJavaFile createDummyJavaFile(String text) {
String ext = StdFileTypes.JAVA.getDefaultExtension();
@NonNls String fileName = "_Dummy_." + ext;
FileType type = StdFileTypes.JAVA;
protected PsiJavaFile createDummyJavaFile(final String text) {
final String fileName = "_Dummy_." + StdFileTypes.JAVA.getDefaultExtension();
final FileType type = StdFileTypes.JAVA;
return (PsiJavaFile)PsiFileFactory.getInstance(myManager.getProject()).createFileFromText(type, fileName, text, 0, text.length());
}
@NotNull
public PsiTypeParameter createTypeParameterFromText(@NotNull String text, PsiElement context)
throws IncorrectOperationException {
final FileElement holderElement = DummyHolderFactory.createHolder(myManager, context).getTreeElement();
TreeElement treeElement = getJavaParsingContext(holderElement).getDeclarationParsing().parseTypeParameterText(text);
if (treeElement == null) {
throw new IncorrectOperationException("Incorrect type parameter \"" + text + "\"");
public PsiTypeParameter createTypeParameterFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, TYPE_PARAMETER, false), context);
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
if (!(element instanceof PsiTypeParameter)) {
throw new IncorrectOperationException("Incorrect type parameter \"" + text + "\".");
}
holderElement.rawAddChildren(treeElement);
return (PsiTypeParameter)SourceTreeToPsiMap.treeElementToPsi(treeElement);
return (PsiTypeParameter)element;
}
@NotNull
public PsiComment createCommentFromText(@NotNull String text, PsiElement context) throws IncorrectOperationException {
PsiJavaFile aFile = createDummyJavaFile(text);
PsiElement[] children = aFile.getChildren();
for (PsiElement aChildren : children) {
public PsiComment createCommentFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
final PsiJavaFile aFile = createDummyJavaFile(text);
for (PsiElement aChildren : aFile.getChildren()) {
if (aChildren instanceof PsiComment) {
if (!aChildren.getText().equals(text)) {
throw new IncorrectOperationException("Incorrect comment \"" + text + "\".");
break;
}
PsiComment comment = (PsiComment)aChildren;
final PsiComment comment = (PsiComment)aChildren;
DummyHolderFactory.createHolder(myManager, (TreeElement)SourceTreeToPsiMap.psiElementToTree(comment), context);
return comment;
}
}
throw new IncorrectOperationException("Incorrect comment \"" + text + "\".");
}
@NotNull
public PsiEnumConstant createEnumConstantFromText(@NotNull String text, PsiElement context) throws IncorrectOperationException {
final FileElement holderElement = DummyHolderFactory.createHolder(myManager, context).getTreeElement();
TreeElement decl = getJavaParsingContext(holderElement).getDeclarationParsing().parseEnumConstantText(text);
if (decl == null || decl.getElementType() != JavaElementType.ENUM_CONSTANT) {
throw new IncorrectOperationException("Incorrect enum constant text \"" + text + "\".");
public PsiEnumConstant createEnumConstantFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, ENUM_CONSTANT, false), context);
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
if (!(element instanceof PsiEnumConstant)) {
throw new IncorrectOperationException("Incorrect enum constant \"" + text + "\".");
}
holderElement.rawAddChildren(decl);
return (PsiEnumConstant)SourceTreeToPsiMap.treeElementToPsi(decl);
return (PsiEnumConstant)element;
}
@NotNull
public PsiCatchSection createCatchSection(@NotNull PsiClassType exceptionType,
@NotNull String exceptionName,
PsiElement context) throws IncorrectOperationException {
@NonNls StringBuilder buffer = new StringBuilder();
buffer.append("catch (");
buffer.append(exceptionType.getCanonicalText());
buffer.append(" ").append(exceptionName).append("){}");
String catchSectionText = buffer.toString();
final FileElement holderElement = DummyHolderFactory.createHolder(myManager, context).getTreeElement();
TreeElement catchSection = getJavaParsingContext(holderElement).getStatementParsing().parseCatchSectionText(catchSectionText);
if (catchSection == null || catchSection.getElementType() != JavaElementType.CATCH_SECTION) {
LOG.error(catchSectionText + "\nPSI:" + (catchSection == null ? null : DebugUtil.treeToString(catchSection, false)));
public PsiCatchSection createCatchSection(@NotNull final PsiClassType exceptionType, @NotNull final String exceptionName,
final PsiElement context) throws IncorrectOperationException {
final String text = join("catch (", exceptionType.getCanonicalText(), " ", exceptionName, ") {}");
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, CATCH_SECTION, false), context);
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
if (!(element instanceof PsiCatchSection)) {
throw new IncorrectOperationException("Incorrect catch section \"" + text + "\".");
}
holderElement.rawAddChildren(catchSection);
PsiCatchSection psiCatchSection = (PsiCatchSection)SourceTreeToPsiMap.treeElementToPsi(catchSection);
setupCatchBlock(exceptionName, context, psiCatchSection);
return (PsiCatchSection)myManager.getCodeStyleManager().reformat(psiCatchSection);
setupCatchBlock(exceptionName, context, (PsiCatchSection)element);
return (PsiCatchSection)myManager.getCodeStyleManager().reformat(element);
}
private void setupCatchBlock(String exceptionName, PsiElement context, PsiCatchSection psiCatchSection)
throws IncorrectOperationException {
FileTemplate catchBodyTemplate = FileTemplateManager.getInstance().getCodeTemplate(JavaTemplateUtil.TEMPLATE_CATCH_BODY);
private void setupCatchBlock(final String exceptionName, final PsiElement context, final PsiCatchSection psiCatchSection)
throws IncorrectOperationException {
final FileTemplate catchBodyTemplate = FileTemplateManager.getInstance().getCodeTemplate(JavaTemplateUtil.TEMPLATE_CATCH_BODY);
LOG.assertTrue(catchBodyTemplate != null);
Properties props = new Properties();
final Properties props = new Properties();
props.setProperty(FileTemplate.ATTRIBUTE_EXCEPTION, exceptionName);
if (context != null && context.isPhysical()) {
PsiDirectory directory = context.getContainingFile().getContainingDirectory();
final PsiDirectory directory = context.getContainingFile().getContainingDirectory();
if (directory != null) {
JavaTemplateUtil.setPackageNameAttribute(props, directory);
}
}
PsiCodeBlock codeBlockFromText;
final PsiCodeBlock codeBlockFromText;
try {
String catchBody = catchBodyTemplate.getText(props);
codeBlockFromText = createCodeBlockFromText("{\n" + catchBody + "\n}", null);
codeBlockFromText = createCodeBlockFromText("{\n" + catchBodyTemplate.getText(props) + "\n}", null);
}
catch (ProcessCanceledException ce) {
throw ce;
}
catch (Exception e) {
throw new IncorrectOperationException("Incorrect file template",e);
throw new IncorrectOperationException("Incorrect file template", e);
}
psiCatchSection.getCatchBlock().replace(codeBlockFromText);
}
public PsiType createPrimitiveType(@NotNull String text, @NotNull PsiAnnotation[] annotations) {
if (annotations.length == 0) {
return PsiElementFactoryImpl.getPrimitiveType(text);//todo
public PsiType createPrimitiveType(@NotNull final String text, @NotNull final PsiAnnotation[] annotations) throws IncorrectOperationException {
final PsiPrimitiveType primitiveType = getPrimitiveType(text);
if (primitiveType == null) {
throw new IncorrectOperationException("Incorrect primitive type \"" + text + "\".");
}
return new PsiPrimitiveType(text, annotations);
return annotations.length == 0 ? primitiveType : new PsiPrimitiveType(text, annotations);
}
public static PsiPrimitiveType getPrimitiveType(final String text) {
return PRIMITIVE_TYPES.get(text);
}
}
@@ -0,0 +1,82 @@
/*
* Copyright 2000-2010 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.impl.source;
import com.intellij.lang.java.parser.JavaParserUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.impl.source.tree.FileElement;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.TreeElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Dummy file element for using together with DummyHolder.
* See {@link com.intellij.psi.impl.PsiJavaParserFacadeImpl} for details.
*/
public class JavaDummyElement extends FileElement {
@NotNull private final JavaParserUtil.ParserWrapper myParser;
private final boolean myConsumeAll;
@NotNull private final LanguageLevel myLanguageLevel;
public JavaDummyElement(@Nullable final CharSequence text, @NotNull final JavaParserUtil.ParserWrapper parser, final boolean consumeAll) {
this(text, parser, consumeAll, LanguageLevel.HIGHEST);
}
public JavaDummyElement(@Nullable final CharSequence text,
@NotNull final JavaParserUtil.ParserWrapper parser,
final boolean consumeAll,
@NotNull final LanguageLevel level) {
super(JavaElementType.DUMMY_ELEMENT, text);
myParser = parser;
myConsumeAll = consumeAll;
myLanguageLevel = level;
}
@NotNull
public JavaParserUtil.ParserWrapper getParser() {
return myParser;
}
public boolean consumeAll() {
return myConsumeAll;
}
@NotNull
public LanguageLevel getLanguageLevel() {
return myLanguageLevel;
}
@Override
public TreeElement getFirstChildNode() {
try {
return super.getFirstChildNode();
}
catch (AssertionError e) {
return null; // masquerade parser errors
}
}
@Override
public TreeElement getLastChildNode() {
try {
return super.getLastChildNode();
}
catch (AssertionError e) {
return null; // masquerade parser errors
}
}
}
@@ -25,7 +25,7 @@ import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.tree.IElementType;
/**
*
* @deprecated old Java parser is deprecated in favor of PSI builder-based one (see com.intellij.lang.java.parser.*) (to remove in IDEA 11).
*/
public class ClassBodyParsing extends Parsing {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.ClassBodyParsing");
@@ -32,7 +32,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
*
* @deprecated old Java parser is deprecated in favor of PSI builder-based one (see com.intellij.lang.java.parser.*) (to remove in IDEA 11).
*/
public class DeclarationParsing extends Parsing {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.DeclarationParsing");
@@ -34,6 +34,9 @@ import com.intellij.psi.tree.TokenSet;
import com.intellij.util.CharTable;
import org.jetbrains.annotations.NotNull;
/**
* @deprecated old Java parser is deprecated in favor of PSI builder-based one (see com.intellij.lang.java.parser.*) (to remove in IDEA 11).
*/
public class ExpressionParsing extends Parsing {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.ExpressionParsing");
@@ -31,7 +31,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
*
* @deprecated old Java parser is deprecated in favor of PSI builder-based one (see com.intellij.lang.java.parser.*) (to remove in IDEA 11).
*/
public class FileTextParsing extends Parsing {
public FileTextParsing(JavaParsingContext context) {
@@ -28,7 +28,7 @@ import com.intellij.psi.TokenType;
import org.jetbrains.annotations.Nullable;
/**
*
* @deprecated old Java parser is deprecated in favor of PSI builder-based one (see com.intellij.lang.java.parser.*) (to remove in IDEA 11).
*/
public class ImportsTextParsing extends Parsing {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.ImportsTextParsing");
@@ -33,6 +33,9 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NonNls;
/**
* todo[r.sh] rewrite and deprecate
*/
public class JavadocParsing extends Parsing {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.JavadocParsing");
@@ -33,6 +33,9 @@ import com.intellij.util.CharTable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @deprecated old Java parser is deprecated in favor of PSI builder-based one (see com.intellij.lang.java.parser.*) (to remove in IDEA 11).
*/
public class Parsing {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.Parsing");
protected static final boolean DEEP_PARSE_BLOCKS_IN_STATEMENTS = false;
@@ -198,8 +201,8 @@ public class Parsing {
return type;
}
public CompositeElement parseTypeWithEllipsis(Lexer lexer, boolean eatLastDot, boolean allowWilcard) {
CompositeElement type = parseType(lexer, eatLastDot, allowWilcard, false);
public CompositeElement parseTypeWithEllipsis(Lexer lexer, boolean eatLastDot, boolean allowWildcard) {
CompositeElement type = parseType(lexer, eatLastDot, allowWildcard, false);
if (type == null) return null;
if (lexer.getTokenType() == JavaTokenType.ELLIPSIS) {
CompositeElement type1 = ASTFactory.composite(JavaElementType.TYPE);
@@ -33,6 +33,9 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* @deprecated old Java parser is deprecated in favor of PSI builder-based one (see com.intellij.lang.java.parser.*) (to remove in IDEA 11).
*/
public class StatementParsing extends Parsing {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.StatementParsing");
@@ -36,7 +36,7 @@ public class PsiDocTagValueManipulator extends AbstractElementManipulator<PsiDoc
range.getEndOffset(),
newContent
);
return (PsiDocTag)tag.replace(JavaPsiFacade.getInstance(tag.getProject()).getElementFactory().createDocTagFromText(replacement.toString(), null));
return (PsiDocTag)tag.replace(JavaPsiFacade.getInstance(tag.getProject()).getElementFactory().createDocTagFromText(replacement.toString()));
}
public TextRange getRangeInElement(final PsiDocTag tag) {
@@ -28,6 +28,7 @@ import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiManager;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.source.JavaDummyElement;
import com.intellij.psi.impl.source.parsing.JavaParsingContext;
import com.intellij.psi.impl.source.parsing.Parsing;
import com.intellij.psi.impl.source.tree.java.PsiCodeBlockImpl;
@@ -40,6 +41,7 @@ import com.intellij.psi.tree.java.IJavaElementType;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.CharTable;
import com.intellij.util.diff.FlyweightCapableTreeStructure;
import org.jetbrains.annotations.Nullable;
import static com.intellij.lang.PsiBuilderUtil.expect;
@@ -158,6 +160,7 @@ public interface JavaElementType {
seq, 0, seq.length(), 0).getFirstChildNode();
}
@Override
public int getErrorsCount(final CharSequence seq, final Project project) {
final Lexer lexer = new JavaLexer(LanguageLevel.HIGHEST);
@@ -184,6 +187,7 @@ public interface JavaElementType {
class ICodeBlockNewElementType extends ICodeBlockElementType implements ILightLazyParseableElementType {
private ICodeBlockNewElementType() { }
@Override
public FlyweightCapableTreeStructure<LighterASTNode> parseContents(final LighterLazyParseableNode chameleon) {
final PsiBuilder builder = JavaParserUtil.createBuilder(chameleon);
StatementParser.parseCodeBlockDeep(builder, true);
@@ -194,6 +198,8 @@ public interface JavaElementType {
ILazyParseableElementType CODE_BLOCK = JavaParserDefinition.USE_NEW_PARSER ? new ICodeBlockNewElementType() : new ICodeBlockElementType();
IElementType STATEMENTS = new ICodeFragmentElementType("STATEMENTS", StdLanguages.JAVA) {
@Nullable
@Override
public ASTNode parseContents(final ASTNode chameleon) {
if (JavaParserDefinition.USE_NEW_PARSER) {
return JavaParserUtil.parseFragment(chameleon,
@@ -213,6 +219,8 @@ public interface JavaElementType {
};
IElementType EXPRESSION_TEXT = new ICodeFragmentElementType("EXPRESSION_TEXT", StdLanguages.JAVA) {
@Nullable
@Override
public ASTNode parseContents(final ASTNode chameleon) {
if (JavaParserDefinition.USE_NEW_PARSER) {
return JavaParserUtil.parseFragment(chameleon,
@@ -231,6 +239,8 @@ public interface JavaElementType {
};
IElementType REFERENCE_TEXT = new ICodeFragmentElementType("REFERENCE_TEXT", StdLanguages.JAVA) {
@Nullable
@Override
public ASTNode parseContents(final ASTNode chameleon) {
if (JavaParserDefinition.USE_NEW_PARSER) {
return JavaParserUtil.parseFragment(chameleon,
@@ -248,6 +258,8 @@ public interface JavaElementType {
};
IElementType TYPE_TEXT = new ICodeFragmentElementType("TYPE_TEXT", StdLanguages.JAVA) {
@Nullable
@Override
public ASTNode parseContents(final ASTNode chameleon) {
if (JavaParserDefinition.USE_NEW_PARSER) {
return JavaParserUtil.parseFragment(chameleon,
@@ -264,4 +276,14 @@ public interface JavaElementType {
SharedImplUtil.findCharTableByTree(chameleon));
}
};
IElementType DUMMY_ELEMENT = new ILazyParseableElementType("DUMMY_ELEMENT", StdLanguages.JAVA) {
@Nullable
@Override
public ASTNode parseContents(final ASTNode chameleon) {
assert chameleon instanceof JavaDummyElement : chameleon;
final JavaDummyElement dummyElement = (JavaDummyElement)chameleon;
return JavaParserUtil.parseFragment(chameleon, dummyElement.getParser(), dummyElement.consumeAll(), dummyElement.getLanguageLevel());
}
};
}
@@ -395,7 +395,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
final CodeStyleManager codeStyleManager = manager.getCodeStyleManager();
@NonNls final StringBuilder fieldBuffer = new StringBuilder();
final String delegateVisibility = calculateDelegateVisibility();
fieldBuffer.append(delegateVisibility).append(' ');
if (delegateVisibility.length() > 0) fieldBuffer.append(delegateVisibility).append(' ');
fieldBuffer.append("final ");
final String fullyQualifiedName = StringUtil.getQualifiedName(newPackageName, newClassName);
fieldBuffer.append(fullyQualifiedName);
@@ -408,8 +408,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
}
fieldBuffer.append(' ');
fieldBuffer.append(delegateFieldName);
fieldBuffer.append('=');
fieldBuffer.append("new ").append(fullyQualifiedName);
fieldBuffer.append(" = new ").append(fullyQualifiedName);
if (!typeParams.isEmpty()) {
fieldBuffer.append('<');
for (PsiTypeParameter typeParameter : typeParams) {
@@ -312,8 +312,7 @@ public class IntroduceParameterObjectProcessor extends FixableUsagesRefactoringP
}
if (compatibleParamObjectConstructor != null) {
PsiDocComment psiDocComment =
JavaPsiFacade.getElementFactory(myProject).createDocCommentFromText("/**\n*/", compatibleParamObjectConstructor);
PsiDocComment psiDocComment = JavaPsiFacade.getElementFactory(myProject).createDocCommentFromText("/**\n*/");
psiDocComment = (PsiDocComment)compatibleParamObjectConstructor.addBefore(psiDocComment, compatibleParamObjectConstructor.getFirstChild());
for (PsiDocTag tag : mergedTags) {
@@ -38,7 +38,8 @@ import java.util.*;
public class RefactoringHierarchyUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.RefactoringHierarchyUtil");
private static final List<PsiType> PRIMITIVE_TYPES = Arrays.asList(
private static final List<? extends PsiType> PRIMITIVE_TYPES = Arrays.asList(
PsiType.BYTE, PsiType.CHAR, PsiType.SHORT, PsiType.INT, PsiType.LONG, PsiType.FLOAT, PsiType.DOUBLE
);
@@ -97,7 +97,7 @@ public class PsiClassConverter extends Converter<PsiClass> implements CustomRefe
@Nullable
protected GlobalSearchScope getScope(final GenericDomValue domValue) {
final Module module = domValue.getModule();
return module == null ? null : GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module);
return module == null ? null : GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, false);
}
public static class AnnotationType extends PsiClassConverter {
@@ -3,6 +3,6 @@ class MyClass {
void foo(int a) {}
{
foo(<caret>)
foo(<caret>);
}
}
@@ -0,0 +1,5 @@
class A {
{
String c = new String();<caret>
}
}
@@ -0,0 +1,5 @@
class A {
{
String c = new Stri<caret>
}
}
@@ -0,0 +1,8 @@
class A {
void foo(String bar, int a) {}
String zoo(int b) {}
{
foo(zoo(), <caret>)
}
}
@@ -0,0 +1,8 @@
class A {
void foo(String bar, int a) {}
String zoo(int b) {}
{
foo(zo<caret>)
}
}
@@ -477,28 +477,26 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
public void testSameNamedFieldAndLocal() throws Throwable { doTest(); }
public void testNoTailWhenNoPairBracket() throws Throwable {
doTestNoPairBracket();
}
public void testNoTailWhenNoPairBracket() throws Throwable { doTestNoPairBracket(Lookup.NORMAL_SELECT_CHAR); }
public void testNoTailWhenNoPairBracket2() throws Throwable {
doTestNoPairBracket();
}
public void testNoTailWhenNoPairBracket2() throws Throwable { doTestNoPairBracket(Lookup.NORMAL_SELECT_CHAR); }
private void doTestNoPairBracket() throws Exception {
private void doTestNoPairBracket(final char c) throws Exception {
boolean old = CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET;
CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET = false;
try {
doTest();
doTest(c);
}
finally {
CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET = old;
}
}
public void testNoConstructorTailWhenNoPairBracket() throws Throwable {
doTestNoPairBracket();
}
public void testNoConstructorTailWhenNoPairBracket() throws Throwable { doTestNoPairBracket(Lookup.NORMAL_SELECT_CHAR); }
public void testConstructorNoPairBracketSemicolon() throws Throwable { doTestNoPairBracket(';'); }
public void testMethodNoPairBracketComma() throws Throwable { doTestNoPairBracket(','); }
public void testAbstractClassTwice() throws Throwable {
configureByTestName();
@@ -58,8 +58,7 @@ public interface PsiElementFactory extends PsiJavaParserFacade {
* @return the created enum instance.
* @throws IncorrectOperationException if <code>name</code> is not a valid Java identifier.
*/
PsiClass createEnum(@NotNull @NonNls String name) throws IncorrectOperationException;
@NotNull PsiClass createEnum(@NotNull @NonNls String name) throws IncorrectOperationException;
/**
* Creates a field with the specified name and type.
@@ -158,7 +157,7 @@ public interface PsiElementFactory extends PsiJavaParserFacade {
*
* @param type the type to detach.
* @return the detached type.
* @deprecated Optimization method, do not use if you do not understand what it does.
* @deprecated does nothing (remove in IDEA 11)
*/
@NotNull PsiType detachType(@NotNull PsiType type);
@@ -189,9 +188,10 @@ public interface PsiElementFactory extends PsiJavaParserFacade {
@Nullable PsiPrimitiveType createPrimitiveType(@NotNull String text);
/**
* The same as {@link #createTypeByFQClassName(String, GlobalSearchScope)} with {@link GlobalSearchScope#allScope()}
* The same as {@link #createTypeByFQClassName(String, GlobalSearchScope)}
* with {@link GlobalSearchScope#allScope(com.intellij.openapi.project.Project)}.
*
* @param qName the full-qualified name of the class to create the reference to.
* @param qName the full-qualified name of the class to create the reference to.
* @return the class type instance.
*/
@NotNull PsiClassType createTypeByFQClassName(@NotNull @NonNls String qName);
@@ -419,6 +419,7 @@ public interface PsiElementFactory extends PsiJavaParserFacade {
/**
* Returns a synthetic Java class containing methods which are defined on Java arrays.
*
* @param languageLevel language level used to construct array class.
* @return the array synthetic class.
*/
@NotNull PsiClass getArrayClass(@NotNull LanguageLevel languageLevel);
@@ -428,7 +429,7 @@ public interface PsiElementFactory extends PsiJavaParserFacade {
* are defined on Java arrays with the specified element type.
*
* @param componentType the component type of the array for which the class type is returned.
* @param languageLevel
* @param languageLevel language level used to construct array class.
* @return the class type the array synthetic class.
*/
@NotNull PsiClassType getArrayClassType(@NotNull PsiType componentType, @NotNull final LanguageLevel languageLevel);
@@ -14,9 +14,6 @@
* limitations under the License.
*/
/*
* @author max
*/
package com.intellij.psi;
import com.intellij.pom.java.LanguageLevel;
@@ -26,28 +23,41 @@ import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
/*
* @author max
*/
public interface PsiJavaParserFacade extends PsiParserFacade {
/**
* Creates a JavaDoc tag from the specified text.
*
* @param docTagText the text of the JavaDoc tag.
* @param context ignored; no longer used
* @return the created tag.
* @throws com.intellij.util.IncorrectOperationException if the text of the tag is not valid.
*/
@NotNull
PsiDocTag createDocTagFromText(@NotNull String docTagText, @Deprecated PsiElement context) throws IncorrectOperationException;
PsiDocTag createDocTagFromText(@NotNull String docTagText) throws IncorrectOperationException;
/**
* @deprecated use {@link #createDocTagFromText(String)} (to remove in IDEA 11)
*/
@NotNull
PsiDocTag createDocTagFromText(@NotNull String docTagText, PsiElement context) throws IncorrectOperationException;
/**
* Creates a JavaDoc comment from the specified text.
*
* @param docCommentText the text of the JavaDoc comment.
* @param context ignored; no longer used
* @return the created comment.
* @throws com.intellij.util.IncorrectOperationException if the text of the comment is not valid.
*/
@NotNull
PsiDocComment createDocCommentFromText(@NotNull String docCommentText, @Deprecated PsiElement context) throws IncorrectOperationException;
PsiDocComment createDocCommentFromText(@NotNull String docCommentText) throws IncorrectOperationException;
/**
* @deprecated use {@link #createDocCommentFromText(String)} (to remove in IDEA 11)
*/
@NotNull
PsiDocComment createDocCommentFromText(@NotNull String docCommentText, PsiElement context) throws IncorrectOperationException;
/**
* Creates a Java class from the specified text.
@@ -110,7 +120,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
* Creates a Java type from the specified text.
*
* @param text the text of the type to create (for example, a primitive type keyword, an array
* declaration or the name of a class)
* declaration or the name of a class).
* @param context the PSI element used as context for resolving the reference.
* @return the created type instance.
* @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid type.
@@ -193,7 +203,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
* type and name.
*
* @param exceptionType the type of the exception to catch.
* @param exceptionName the name of the variable in which the caught exception is stored (may be an empty string)
* @param exceptionName the name of the variable in which the caught exception is stored (may be an empty string).
* @param context the context for resolving references.
* @return the created catch section instance.
* @throws IncorrectOperationException if some of the parameters are not valid.
@@ -201,5 +211,13 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
@NotNull PsiCatchSection createCatchSection(@NotNull PsiClassType exceptionType, @NotNull String exceptionName, PsiElement context)
throws IncorrectOperationException;
PsiType createPrimitiveType(@NotNull String text, @NotNull PsiAnnotation[] annotations);
/**
* Creates a Java type from the specified text.
*
* @param text the text of the type to create (a primitive type keyword).
* @param annotations array (possible empty) of annotations to annotate the created type.
* @return the created type instance.
* @throws IncorrectOperationException if some of the parameters are not valid.
*/
PsiType createPrimitiveType(@NotNull String text, @NotNull PsiAnnotation[] annotations) throws IncorrectOperationException;
}
+11 -10
View File
@@ -27,16 +27,17 @@ import org.jetbrains.annotations.Nullable;
* Representation of Java type (primitive type, array or class type).
*/
public abstract class PsiType implements PsiAnnotationOwner {
public static final PsiType BYTE = new PsiPrimitiveType("byte", "java.lang.Byte");
public static final PsiType CHAR = new PsiPrimitiveType("char", "java.lang.Character");
public static final PsiType DOUBLE = new PsiPrimitiveType("double", "java.lang.Double");
public static final PsiType FLOAT = new PsiPrimitiveType("float", "java.lang.Float");
public static final PsiType INT = new PsiPrimitiveType("int", "java.lang.Integer");
public static final PsiType LONG = new PsiPrimitiveType("long", "java.lang.Long");
public static final PsiType SHORT = new PsiPrimitiveType("short", "java.lang.Short");
public static final PsiType BOOLEAN = new PsiPrimitiveType("boolean", "java.lang.Boolean");
public static final PsiType VOID = new PsiPrimitiveType("void", "java.lang.Void");
public static final PsiType NULL = new PsiPrimitiveType("null", (String)null);
public static final PsiPrimitiveType BYTE = new PsiPrimitiveType("byte", "java.lang.Byte");
public static final PsiPrimitiveType CHAR = new PsiPrimitiveType("char", "java.lang.Character");
public static final PsiPrimitiveType DOUBLE = new PsiPrimitiveType("double", "java.lang.Double");
public static final PsiPrimitiveType FLOAT = new PsiPrimitiveType("float", "java.lang.Float");
public static final PsiPrimitiveType INT = new PsiPrimitiveType("int", "java.lang.Integer");
public static final PsiPrimitiveType LONG = new PsiPrimitiveType("long", "java.lang.Long");
public static final PsiPrimitiveType SHORT = new PsiPrimitiveType("short", "java.lang.Short");
public static final PsiPrimitiveType BOOLEAN = new PsiPrimitiveType("boolean", "java.lang.Boolean");
public static final PsiPrimitiveType VOID = new PsiPrimitiveType("void", "java.lang.Void");
public static final PsiPrimitiveType NULL = new PsiPrimitiveType("null", (String)null);
public static final PsiType[] EMPTY_ARRAY = new PsiType[0];
private final PsiAnnotation[] myAnnotations;
@@ -41,7 +41,7 @@ public class DomJavaUtil {
if (searchScope == null) {
if (module != null) {
scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module);
scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, false);
}
else {
scope = file.getResolveScope();
@@ -22,6 +22,7 @@ import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.IntentionManager;
import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.codeInspection.InspectionToolProvider;
@@ -33,13 +34,19 @@ import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
import com.intellij.codeInspection.ex.ToolsImpl;
import com.intellij.ide.startup.StartupManagerEx;
import com.intellij.ide.startup.impl.StartupManagerImpl;
import com.intellij.lang.ExternalAnnotatorsFilter;
import com.intellij.lang.LanguageAnnotators;
import com.intellij.lang.StdLanguages;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.startup.StartupManager;
@@ -57,15 +64,19 @@ import com.intellij.profile.codeInspection.InspectionProfileManager;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.*;
import com.intellij.psi.impl.JavaPsiFacadeEx;
import com.intellij.psi.impl.search.IndexPatternBuilder;
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.impl.source.tree.TreeUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.UsageSearchContext;
import com.intellij.psi.xml.XmlFileNSInfoProvider;
import com.intellij.testFramework.ExpectedHighlightingData;
import com.intellij.testFramework.FileTreeAccessFilter;
import com.intellij.testFramework.LightPlatformTestCase;
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
import com.intellij.util.IncorrectOperationException;
import com.intellij.xml.XmlSchemaProvider;
import gnu.trove.THashMap;
import gnu.trove.TIntArrayList;
import org.jetbrains.annotations.NonNls;
@@ -160,6 +171,21 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false);
myRunCommandForTest = !annotatedWith(DoNotWrapInCommand.class);
if (isPerformanceTest()) {
IntentionManager.getInstance().getAvailableIntentionActions(); // hack to avoid slowdowns in PyExtensionFactory
PathManagerEx.getTestDataPath(); // to cache stuff
ReferenceProvidersRegistry.getInstance(getProject()); // preload tons of classes
InjectedLanguageManager.getInstance(getProject()); // zillion of Dom Sem classes
LanguageAnnotators.INSTANCE.allForLanguage(StdLanguages.JAVA); // pile of annotator classes loads
LanguageAnnotators.INSTANCE.allForLanguage(StdLanguages.XML);
ProblemHighlightFilter.EP_NAME.getExtensions();
Extensions.getExtensions(ImplicitUsageProvider.EP_NAME);
Extensions.getExtensions(XmlSchemaProvider.EP_NAME);
Extensions.getExtensions(XmlFileNSInfoProvider.EP_NAME);
Extensions.getExtensions(ExternalAnnotatorsFilter.EXTENSION_POINT_NAME);
Extensions.getExtensions(IndexPatternBuilder.EP_NAME);
}
}
@Override
@@ -235,6 +235,11 @@ public class LookupElementBuilder extends LookupElement {
return true;
}
@Override
public String toString() {
return "LookupElementBuilder: string=" + getLookupString() + "; handler=" + myInsertHandler;
}
@Override
public int hashCode() {
int result = 0;
@@ -11,6 +11,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
import com.intellij.util.net.HttpConfigurable;
import com.intellij.util.xmlb.XmlSerializationException;
import com.intellij.util.xmlb.XmlSerializer;
import org.jetbrains.annotations.NotNull;
@@ -46,11 +47,17 @@ public class LibrariesDownloadAssistant {
final String serviceUrl = LibrariesDownloadConnectionService.getInstance().getServiceUrl();
if (StringUtil.isNotEmpty(serviceUrl)) {
try {
return new URL(serviceUrl + "/" + id + "/");
final String url = serviceUrl + "/" + id + "/";
HttpConfigurable.getInstance().prepareURL(url);
return new URL(url);
}
catch (MalformedURLException e) {
LOG.error(e);
}
catch (IOException e) {
LOG.error(e);
}
}
return null;
@@ -0,0 +1,95 @@
/*
* Copyright 2000-2010 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.facet.frameworks.ui;
import com.intellij.facet.frameworks.LibrariesDownloadAssistant;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.ui.CollectionComboBoxModel;
import com.intellij.util.ui.update.Activatable;
import com.intellij.util.ui.update.UiNotifyConnector;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class LibrariesDownloadUiUtil {
private LibrariesDownloadUiUtil() {
}
public static JComboBox createVersionsCombobox(@NotNull final String groupId, final URL... localUrls) {
final JComboBox jComboBox = new JComboBox();
initAsyncComboBoxModel(jComboBox, groupId, localUrls);
return jComboBox;
}
public static void initAsyncComboBoxModel(@NotNull final JComboBox jComboBox,
@NotNull final String groupId,
final URL... localUrls) {
final List<Object> items = new ArrayList<Object>();
new UiNotifyConnector.Once(jComboBox, new Activatable() {
@Override
public void showNotify() {
loadItems(jComboBox, items, groupId, localUrls);
}
@Override
public void hideNotify() {
}
});
items.add("loading...");
jComboBox.setModel(new CollectionComboBoxModel(items, items.get(0)));
jComboBox.setEnabled(false);
}
private static void loadItems(@NotNull final JComboBox jComboBox,
final List<Object> items,
final String groupId,
final URL... localUrls) {
final ModalityState state = ModalityState.current();
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
final List<Object> newItems = new ArrayList<Object>();
newItems.addAll(Arrays.asList(LibrariesDownloadAssistant.getVersions(groupId, localUrls)));
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
items.clear();
if (!newItems.isEmpty()) {
items.addAll(newItems);
final CollectionComboBoxModel model = (CollectionComboBoxModel)jComboBox.getModel();
model.update();
jComboBox.setSelectedIndex(0);
}
jComboBox.setEnabled(true);
}
}, state);
}
}
);
}
}
@@ -41,6 +41,7 @@ public class FoldingDescriptor {
private final TextRange myRange;
@Nullable private final FoldingGroup myGroup;
private Set<Object> myDependencies;
private final boolean myNeverExpands;
/**
* Creates a folding region related to the specified AST node and covering the specified
@@ -66,14 +67,33 @@ public class FoldingDescriptor {
* Creates a folding region related to the specified AST node and covering the specified
* text range.
* @param node The node to which the folding region is related. The node is then passed to
* {@link FoldingBuilder#getPlaceholderText(com.intellij.lang.ASTNode)} and
* {@link FoldingBuilder#isCollapsedByDefault(com.intellij.lang.ASTNode)}.
* {@link com.intellij.lang.folding.FoldingBuilder#getPlaceholderText(com.intellij.lang.ASTNode)} and
* {@link com.intellij.lang.folding.FoldingBuilder#isCollapsedByDefault(com.intellij.lang.ASTNode)}.
* @param range The folded text range.
* @param group Regions with the same group instance expand and collapse together.
* @param dependencies folding dependencies: other files or elements that could change
* folding description
*/
public FoldingDescriptor(@NotNull ASTNode node, @NotNull TextRange range, @Nullable FoldingGroup group, Set<Object> dependencies) {
this(node, range, group, dependencies, false);
}
/**
* Creates a folding region related to the specified AST node and covering the specified
* text range.
* @param node The node to which the folding region is related. The node is then passed to
* {@link com.intellij.lang.folding.FoldingBuilder#getPlaceholderText(com.intellij.lang.ASTNode)} and
* {@link com.intellij.lang.folding.FoldingBuilder#isCollapsedByDefault(com.intellij.lang.ASTNode)}.
* @param range The folded text range.
* @param group Regions with the same group instance expand and collapse together.
* @param dependencies folding dependencies: other files or elements that could change
* @param neverExpands shall be true for fold regions that must not be ever expanded.
*/
public FoldingDescriptor(@NotNull ASTNode node,
@NotNull TextRange range,
@Nullable FoldingGroup group,
Set<Object> dependencies,
boolean neverExpands) {
assert range.getStartOffset() + 1 < range.getEndOffset() : range;
myElement = node;
ProperTextRange.assertProperRange(range);
@@ -81,6 +101,7 @@ public class FoldingDescriptor {
myGroup = group;
assert getRange().getLength() >= 2 : "range:" + getRange();
myDependencies = dependencies;
myNeverExpands = neverExpands;
}
/**
@@ -122,4 +143,8 @@ public class FoldingDescriptor {
public Set<Object> getDependencies() {
return myDependencies;
}
public boolean isNonExpandable() {
return myNeverExpands;
}
}
@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.application.options.InitialConfigurationDialog">
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="4" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="9a864" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="d7106"/>
<text value="Keyboard Shortcuts Scheme:"/>
</properties>
</component>
<vspacer id="fd0af">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="9f9cd" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="f7d28"/>
<text value="Color Scheme:"/>
</properties>
</component>
<component id="d7106" class="javax.swing.JComboBox" binding="myKeymapComboBox" default-binding="true">
<constraints>
<grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="f7d28" class="javax.swing.JComboBox" binding="myColorSchemeComboBox" default-binding="true">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="978ed" class="javax.swing.JLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="You can use the Settings dialog to configure any of these settings later."/>
</properties>
</component>
<component id="d63d7" class="javax.swing.JButton" binding="myPreviewButton" default-binding="true">
<constraints>
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Preview"/>
</properties>
</component>
</children>
</grid>
<buttonGroups>
<group name="buttonGroup1">
<member id="a58"/>
<member id="e7ab9"/>
</group>
</buttonGroups>
</form>
@@ -0,0 +1,172 @@
package com.intellij.application.options;
import com.intellij.application.options.colors.ColorAndFontOptions;
import com.intellij.application.options.colors.NewColorAndFontPanel;
import com.intellij.application.options.colors.SimpleEditorPreview;
import com.intellij.ide.todo.TodoConfiguration;
import com.intellij.ide.ui.ListCellRendererWrapper;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.keymap.Keymap;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.keymap.impl.KeymapManagerImpl;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.SystemInfo;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
/**
* @author yole
*/
public class InitialConfigurationDialog extends DialogWrapper {
private JPanel myMainPanel;
private JComboBox myKeymapComboBox;
private JComboBox myColorSchemeComboBox;
private JButton myPreviewButton;
private String myColorSettingsPage;
public InitialConfigurationDialog(Component parent, String colorSettingsPage) {
super(parent, true);
myColorSettingsPage = colorSettingsPage;
setTitle(ApplicationNamesInfo.getInstance().getFullProductName() + " Initial Configuration");
final ArrayList<Keymap> keymaps = new ArrayList<Keymap>();
for (Keymap keymap : ((KeymapManagerImpl)KeymapManager.getInstance()).getAllKeymaps()) {
if (matchesPlatform(keymap)) {
keymaps.add(keymap);
}
}
myKeymapComboBox.setModel(new DefaultComboBoxModel(keymaps.toArray(new Keymap[keymaps.size()])));
myKeymapComboBox.setRenderer(new ListCellRendererWrapper(myKeymapComboBox.getRenderer()) {
@Override
public void customize(final JList list, final Object value, final int index, final boolean selected, final boolean cellHasFocus) {
Keymap keymap = (Keymap)value;
if (keymap == null) {
return;
}
if (KeymapManager.DEFAULT_IDEA_KEYMAP.equals(keymap.getName())) {
setText("IntelliJ IDEA Classic");
}
else if ("Mac OS X".equals(keymap.getName())) {
setText("IntelliJ IDEA Classic - Mac OS X");
}
else {
setText(keymap.getPresentableName());
}
}
});
preselectKeyMap(keymaps);
final EditorColorsScheme[] colorSchemes = EditorColorsManager.getInstance().getAllSchemes();
myColorSchemeComboBox.setModel(new DefaultComboBoxModel(colorSchemes));
myColorSchemeComboBox.setRenderer(new ListCellRendererWrapper(myColorSchemeComboBox.getRenderer()) {
@Override
public void customize(JList list, Object value, int index, boolean selected, boolean cellHasFocus) {
setText(((EditorColorsScheme)value).getName());
}
});
init();
myPreviewButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
showColorSchemePreviewDialog();
}
});
}
private void preselectKeyMap(ArrayList<Keymap> keymaps) {
if (SystemInfo.isMac) {
for (Keymap keymap : keymaps) {
if (keymap.getName().equals("Default for Mac OS X")) {
myKeymapComboBox.setSelectedItem(keymap);
break;
}
}
}
}
private static boolean matchesPlatform(Keymap keymap) {
if (keymap.getName().equals(KeymapManager.DEFAULT_IDEA_KEYMAP)) {
return !SystemInfo.isMac;
}
else if (keymap.getName().equals(KeymapManager.MAC_OS_X_KEYMAP)) {
return SystemInfo.isMac;
}
else if (keymap.getName().equals("Default for GNOME") || keymap.getName().equals("Default for KDE") ||
keymap.getName().equals("Default for XWin")) {
return SystemInfo.isLinux;
}
return true;
}
private void showColorSchemePreviewDialog() {
showColorSchemePreviewDialog(ColorAndFontOptions.getColorAndFontsInstance());
}
private void showColorSchemePreviewDialog(final ColorAndFontOptions options) {
final NewColorAndFontPanel page = options.findPage(myColorSettingsPage);
assert page != null;
options.reset();
final String selectedScheme = ((EditorColorsScheme)myColorSchemeComboBox.getSelectedItem()).getName();
options.selectScheme(selectedScheme);
final SimpleEditorPreview preview = new SimpleEditorPreview(options, page.getSettingsPage());
preview.updateView();
DialogWrapper wrapper = new PreviewDialog(preview, selectedScheme);
wrapper.show();
preview.disposeUIResources();
options.disposeUIResources();
}
protected JComponent createCenterPanel() {
return myMainPanel;
}
@Override
protected void doOKAction() {
super.doOKAction();
// set keymap
((KeymapManagerImpl)KeymapManager.getInstance()).setActiveKeymap((Keymap)myKeymapComboBox.getSelectedItem());
// set color scheme
EditorColorsManager.getInstance().setGlobalScheme((EditorColorsScheme)myColorSchemeComboBox.getSelectedItem());
// create default todo_pattern for color scheme
TodoConfiguration.getInstance().resetToDefaultTodoPatterns();
}
private class PreviewDialog extends DialogWrapper {
private final SimpleEditorPreview myPreview;
public PreviewDialog(final SimpleEditorPreview preview, final String selectedScheme) {
super(myMainPanel, true);
myPreview = preview;
setTitle("Preview for " + selectedScheme);
init();
}
@Override
protected JComponent createCenterPanel() {
JPanel panel = new JPanel(new BorderLayout()) {
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
};
panel.add(myPreview.getPanel(), BorderLayout.CENTER);
return panel;
}
@Override
protected Action[] createActions() {
final Action action = getOKAction();
action.putValue(Action.NAME, "Close");
return new Action[]{action};
}
}
}
@@ -34,6 +34,7 @@ import com.intellij.openapi.application.ApplicationAdapter;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
@@ -157,7 +158,13 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
EditorUtil.fillVirtualSpaceUntilCaret(editor);
documentManager.commitAllDocuments();
assert editor.getDocument().getTextLength() == psiFile.getTextLength() : "unsuccessful commit";
if (editor.getDocument().getTextLength() != psiFile.getTextLength()) {
if (ApplicationManagerEx.getApplicationEx().isInternal()) {
throw new AssertionError("unsuccessful commit: docText=" + editor.getDocument().getText() + "; fileText=" + psiFile.getText() + "; injected=" + (editor instanceof EditorWindow));
}
throw new AssertionError("unsuccessful commit: injected=" + (editor instanceof EditorWindow));
}
final Ref<CompletionContributor> current = Ref.create(null);
initializationContext[0] = new CompletionInitializationContext(editor, psiFile, myCompletionType) {
@@ -67,7 +67,7 @@ public class UnSelectWordHandler extends EditorActionHandler {
int caretOffset = editor.getCaretModel().getOffset();
if (caretOffset > 0 &&
if (caretOffset > 0 && caretOffset < text.length() &&
!Character.isJavaIdentifierPart(text.charAt(caretOffset)) &&
Character.isJavaIdentifierPart(text.charAt(caretOffset - 1))) {
caretOffset--;
@@ -95,7 +95,10 @@ class UpdateFoldRegionsOperation implements Runnable {
FoldingGroup group = descriptor.getGroup();
TextRange range = descriptor.getRange();
String placeholder = descriptor.getPlaceholderText();
FoldRegion region = foldingModel.createFoldRegion(range.getStartOffset(), range.getEndOffset(), placeholder == null ? "..." : placeholder, group);
FoldRegion region = foldingModel.createFoldRegion(range.getStartOffset(), range.getEndOffset(),
placeholder == null ? "..." : placeholder,
group,
descriptor.isNonExpandable());
if (region == null) continue;
if (!foldingModel.addFoldRegion(region)) {
@@ -106,7 +109,7 @@ class UpdateFoldRegionsOperation implements Runnable {
info.addRegion(region, smartPointerManager.createSmartPsiElementPointer(descriptor.getElement().getPsi()));
newRegions.add(region);
boolean expandStatus = shouldExpandNewRegion(element, range, rangeToExpandStatusMap);
boolean expandStatus = !descriptor.isNonExpandable() && shouldExpandNewRegion(element, range, rangeToExpandStatusMap);
if (group == null) {
shouldExpand.put(region, expandStatus);
}
@@ -1185,7 +1185,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
String commandLinePlaceholder = myCommandLineFolding.getPlaceholder(line);
if (commandLinePlaceholder != null) {
FoldRegion region = ((FoldingModelEx)myEditor.getFoldingModel()).createFoldRegion(
document.getLineStartOffset(line), document.getLineEndOffset(line), commandLinePlaceholder, null
document.getLineStartOffset(line), document.getLineEndOffset(line), commandLinePlaceholder, null, false
);
toAdd.add(region);
return;
@@ -1218,7 +1218,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
int oEnd = CharArrayUtil.shiftBackward(chars, document.getLineEndOffset(lEnd) - 1, " \t") + 1;
FoldRegion region =
((FoldingModelEx)myEditor.getFoldingModel()).createFoldRegion(oStart, oEnd, prevFolding.getPlaceholderText(toFold), null);
((FoldingModelEx)myEditor.getFoldingModel()).createFoldRegion(oStart, oEnd, prevFolding.getPlaceholderText(toFold), null, false);
if (region != null) {
toAdd.add(region);
}
@@ -32,6 +32,7 @@ import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.InvalidDnDOperationException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@@ -89,9 +90,14 @@ public class PsiCopyPasteManager {
Object transferData;
try {
transferData = content.getTransferData(ourDataFlavor);
} catch (UnsupportedFlavorException e) {
}
catch (UnsupportedFlavorException e) {
return null;
} catch (IOException e) {
}
catch (IOException e) {
return null;
}
catch (InvalidDnDOperationException e) {
return null;
}
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.ide.scriptingContext.ui.EditLibraryDialog">
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="10" bottom="10" right="10"/>
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="48" y="54" width="775" height="297"/>
<xy x="48" y="54" width="946" height="381"/>
</constraints>
<properties/>
<border type="none"/>
@@ -29,18 +29,19 @@
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Name:"/>
<labelFor value="c2bfa"/>
<text resource-bundle="messages/IdeBundle" key="scripting.lib.name"/>
</properties>
</component>
</children>
</grid>
<grid id="e01b6" layout-manager="GridLayoutManager" row-count="5" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="e01b6" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="2" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none" title="Files:"/>
<border type="none" title-resource-bundle="messages/IdeBundle" title-key="scripting.lib.file.title"/>
<children>
<component id="98c78" class="javax.swing.JButton" binding="myAddFileButton">
<constraints>
@@ -52,7 +53,7 @@
</component>
<scrollpane id="2fb19" class="com.intellij.ui.components.JBScrollPane">
<constraints>
<grid row="0" column="0" row-span="4" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
<grid row="0" column="0" row-span="3" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false">
<minimum-size width="600" height="-1"/>
<preferred-size width="-1" height="200"/>
</grid>
@@ -72,7 +73,7 @@
</scrollpane>
<vspacer id="36d74">
<constraints>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="1dade" class="javax.swing.JButton" binding="myRemoveFileButton">
@@ -83,6 +84,66 @@
<text resource-bundle="messages/IdeBundle" key="scripting.lib.detach"/>
</properties>
</component>
<hspacer id="c4815">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
<grid id="2a02c" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none" title-resource-bundle="messages/IdeBundle" title-key="scripting.lib.docUrl.title"/>
<children>
<component id="fad1f" class="javax.swing.JButton" binding="myAddDocUrlButton">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/IdeBundle" key="scripting.lib.docUrl.specify"/>
</properties>
</component>
<component id="2c3dd" class="javax.swing.JButton" binding="myRemoveDocUrlButton">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/IdeBundle" key="scripting.lib.docUrl.remove"/>
</properties>
</component>
<scrollpane id="2e869" class="com.intellij.ui.components.JBScrollPane">
<constraints>
<grid row="0" column="0" row-span="3" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
<minimum-size width="600" height="-1"/>
</grid>
</constraints>
<properties>
<horizontalScrollBarPolicy value="31"/>
</properties>
<border type="none"/>
<children>
<component id="3d6e4" class="com.intellij.ui.components.JBList" binding="myDocUrlList">
<constraints/>
<properties>
<selectionMode value="0"/>
</properties>
</component>
</children>
</scrollpane>
<vspacer id="6b5fa">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<hspacer id="128aa">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
</children>
@@ -20,16 +20,21 @@ import com.intellij.ide.scriptingContext.LangScriptingContextProvider;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.ui.Util;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.scripting.ScriptingLibraryTable;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.components.JBList;
import com.intellij.ui.table.JBTable;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
@@ -52,10 +57,14 @@ public class EditLibraryDialog extends DialogWrapper {
private JButton myAddFileButton;
private JButton myRemoveFileButton;
private JBTable myFileTable;
private JButton myAddDocUrlButton;
private JButton myRemoveDocUrlButton;
private JBList myDocUrlList;
private Project myProject;
private FileTableModel myFileTableModel;
private VirtualFile mySelectedFile;
private LangScriptingContextProvider myProvider;
private MyDocUrlListModel myDocUrlListModel;
public EditLibraryDialog(String title, LangScriptingContextProvider provider, Project project) {
super(true);
@@ -87,6 +96,44 @@ public class EditLibraryDialog extends DialogWrapper {
updateSelection();
}
});
myDocUrlListModel = new MyDocUrlListModel();
myDocUrlList.setModel(myDocUrlListModel);
myDocUrlListModel.addListDataListener(new ListDataListener() {
@Override
public void intervalAdded(ListDataEvent e) {
myRemoveDocUrlButton.setEnabled(true);
}
@Override
public void intervalRemoved(ListDataEvent e) {
Object source = e.getSource();
if (source instanceof MyDocUrlListModel && ((MyDocUrlListModel)source).getDocUrls().length == 0) {
myRemoveDocUrlButton.setEnabled(false);
}
}
@Override
public void contentsChanged(ListDataEvent e) {
// do nothing
}
});
myAddDocUrlButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
specifyDocUrl();
}
});
myRemoveDocUrlButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
removeDocUrl();
}
});
myRemoveDocUrlButton.setEnabled(false);
init();
TableColumn typeCol = myFileTable.getColumnModel().getColumn(FILE_TYPE_COL);
@@ -99,6 +146,11 @@ public class EditLibraryDialog extends DialogWrapper {
this(title, provider, project);
myLibName.setText(lib.getName());
myFileTableModel.setFiles(lib.getSourceFiles(), lib.getCompactFiles());
String[] docUrls = lib.getDocUrls();
myDocUrlListModel.setDocUrls(docUrls);
if (docUrls.length > 0) {
myRemoveDocUrlButton.setEnabled(true);
}
}
private class MyTableCellEditor extends DefaultCellEditor {
@@ -311,6 +363,10 @@ public class EditLibraryDialog extends DialogWrapper {
public VirtualFile[] getCompactFiles() {
return myFileTableModel.getCompactFiles();
}
public String[] getDocUrls() {
return myDocUrlListModel.getDocUrls();
}
@Override
protected void doOKAction() {
@@ -324,4 +380,61 @@ public class EditLibraryDialog extends DialogWrapper {
private static boolean isLibNameValid(String libName) {
return libName != null && libName.matches("\\w[\\w\\d\\._\\-\\d]*");
}
private static class MyDocUrlListModel extends AbstractListModel {
private ArrayList<String> myDocUrls = new ArrayList<String>();
public void setDocUrls(String[] urls) {
if (urls != null && urls.length > 0) {
myDocUrls.addAll(Arrays.asList(urls));
}
}
@Override
public int getSize() {
return myDocUrls.size();
}
@Override
public Object getElementAt(int index) {
return myDocUrls.get(index);
}
public int addUrl(String url) {
myDocUrls.add(url);
int newIndex = myDocUrls.indexOf(url);
fireIntervalAdded(this, newIndex, newIndex);
return newIndex;
}
public int indexOf(String url) {
return myDocUrls.indexOf(url);
}
public void remove(String url) {
if (url == null || !myDocUrls.contains(url)) return;
int index = myDocUrls.indexOf(url);
myDocUrls.remove(url);
fireIntervalRemoved(this, index, index);
}
public String[] getDocUrls() {
return ArrayUtil.toStringArray(myDocUrls);
}
}
private void specifyDocUrl() {
VirtualFile vf = Util.showSpecifyJavadocUrlDialog(contentPane);
if (vf != null && vf.isValid()) {
String url = vf.getUrl();
int index = myDocUrlListModel.addUrl(url);
myDocUrlList.ensureIndexIsVisible(index);
myDocUrlList.setSelectedIndex(index);
}
}
private void removeDocUrl() {
myDocUrlListModel.remove((String)myDocUrlList.getSelectedValue());
}
}
@@ -96,7 +96,8 @@ public class ScriptingLibrariesPanel extends ScriptingLibrariesPanelStub {
EditLibraryDialog editLibDialog = new EditLibraryDialog("New Library", myProvider, myProject);
editLibDialog.show();
if (editLibDialog.isOK()) {
myLibTableModel.createLibrary(editLibDialog.getLibName(), editLibDialog.getSourceFiles(), editLibDialog.getCompactFiles(), null);
myLibTableModel.createLibrary(editLibDialog.getLibName(), editLibDialog.getSourceFiles(), editLibDialog.getCompactFiles(),
editLibDialog.getDocUrls());
}
}
@@ -129,7 +130,8 @@ public class ScriptingLibrariesPanel extends ScriptingLibrariesPanelStub {
editLibDialog.show();
if (editLibDialog.isOK()) {
myLibTableModel
.updateLibrary(libName, editLibDialog.getLibName(), editLibDialog.getSourceFiles(), editLibDialog.getCompactFiles(), null);
.updateLibrary(libName, editLibDialog.getLibName(), editLibDialog.getSourceFiles(), editLibDialog.getCompactFiles(),
editLibDialog.getDocUrls());
}
}
}
@@ -63,7 +63,7 @@ public class FoldingModelWindow implements FoldingModelEx{
}
public FoldRegion addFoldRegion(int startOffset, int endOffset, @NotNull String placeholderText) {
FoldRegion region = createFoldRegion(startOffset, endOffset, placeholderText, null);
FoldRegion region = createFoldRegion(startOffset, endOffset, placeholderText, null, false);
if (region == null) return null;
if (!addFoldRegion(region)) {
region.dispose();
@@ -129,10 +129,10 @@ public class FoldingModelWindow implements FoldingModelEx{
}
private static final Key<FoldingRegionWindow> FOLD_REGION_WINDOW = Key.create("FOLD_REGION_WINDOW");
public FoldRegion createFoldRegion(int startOffset, int endOffset, @NotNull String placeholder, FoldingGroup group) {
public FoldRegion createFoldRegion(int startOffset, int endOffset, @NotNull String placeholder, FoldingGroup group, boolean neverExpands) {
TextRange hostRange = myDocumentWindow.injectedToHost(new TextRange(startOffset, endOffset));
if (hostRange.getLength() < 2) return null;
FoldRegion hostRegion = myDelegate.createFoldRegion(hostRange.getStartOffset(), hostRange.getEndOffset(), placeholder, group);
FoldRegion hostRegion = myDelegate.createFoldRegion(hostRange.getStartOffset(), hostRange.getEndOffset(), placeholder, group, false);
FoldingRegionWindow window = new FoldingRegionWindow(myDocumentWindow, myEditorWindow, (FoldRegionImpl)hostRegion);
hostRegion.putUserData(FOLD_REGION_WINDOW, window);
return window;
@@ -56,6 +56,11 @@ public class FoldingRegionWindow extends RangeMarkerWindow implements FoldRegion
return myHostRegion.getGroup();
}
@Override
public boolean shouldNeverExpand() {
return false;
}
public FoldRegionImpl getDelegate() {
return myHostRegion;
}
@@ -93,7 +93,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
private int myLexemeCount = 0;
private boolean myTokenTypeChecked;
private ITokenTypeRemapper myRemapper;
private WhitespaceSkippedCallback myWhispaceSkippedCallback;
private WhitespaceSkippedCallback myWhitespaceSkippedCallback;
private ASTNode myOriginalTree = null;
@@ -620,13 +620,22 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
@Nullable
@Override
public IElementType lookAhead(int steps) {
if (steps + myCurrentLexeme >= myLexemeCount) return null;
return myLexTypes[myCurrentLexeme + steps];
int cur = myCurrentLexeme;
while (steps > 0) {
while (cur < myLexemeCount && whitespaceOrComment(myLexTypes[cur])) {
cur++;
}
steps--;
}
return cur < myLexemeCount ? myLexTypes[cur] : null;
}
@Override
public void setWhitespaceSkippedCallback(WhitespaceSkippedCallback callback) {
myWhispaceSkippedCallback = callback;
myWhitespaceSkippedCallback = callback;
}
public void advanceLexer() {
@@ -647,8 +656,8 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
}
private void onSkip(IElementType type, int start, int end) {
if (myWhispaceSkippedCallback != null) {
myWhispaceSkippedCallback.onSkip(type, start, end);
if (myWhitespaceSkippedCallback != null) {
myWhitespaceSkippedCallback.onSkip(type, start, end);
}
}
@@ -37,6 +37,7 @@ import com.intellij.openapi.module.impl.scopes.ModuleWithDependentsScope;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.impl.storage.ClasspathStorage;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.PathUtil;
@@ -322,16 +323,12 @@ public class ModuleImpl extends ComponentManagerImpl implements Module {
@SuppressWarnings({"HardCodedStringLiteral"})
public String toString() {
return "Module:" + getName() + " path:" + getModuleFilePath();
if (myName == null) return "Module"; // was called before initialized
return "Module: '" + getName() + "' path: '" + getModuleFilePath()+"'";
}
private static String moduleNameByFileName(String fileName) {
if (fileName.endsWith(ModuleFileType.DOT_DEFAULT_EXTENSION)) {
return fileName.substring(0, fileName.length() - ModuleFileType.DOT_DEFAULT_EXTENSION.length());
}
else {
return fileName;
}
private static String moduleNameByFileName(@NotNull String fileName) {
return StringUtil.trimEnd(fileName, ModuleFileType.DOT_DEFAULT_EXTENSION);
}
public <T> T[] getExtensions(final ExtensionPointName<T> extensionPointName) {
@@ -48,21 +48,22 @@ abstract class OrderEnumeratorBase extends OrderEnumerator {
protected boolean myRecursivelyExportedOnly;
private boolean myExportedOnly;
private Condition<OrderEntry> myCondition;
private List<OrderEnumerationHandler> myCustomHandlers;
private final List<OrderEnumerationHandler> myCustomHandlers;
protected ModulesProvider myModulesProvider;
private OrderRootsCache myCache;
public OrderEnumeratorBase(@Nullable Module module, @NotNull Project project, @Nullable OrderRootsCache cache) {
myCache = cache;
List<OrderEnumerationHandler> customHandlers = null;
for (OrderEnumerationHandler handler : OrderEnumerationHandler.EP_NAME.getExtensions()) {
if (handler.isApplicable(project) && (module == null || handler.isApplicable(module))) {
if (myCustomHandlers == null) {
myCustomHandlers = new SmartList<OrderEnumerationHandler>();
if (customHandlers == null) {
customHandlers = new SmartList<OrderEnumerationHandler>();
}
myCustomHandlers.add(handler);
customHandlers.add(handler);
}
if (myCustomHandlers == null) myCustomHandlers = Collections.emptyList();
}
this.myCustomHandlers = customHandlers == null ? Collections.<OrderEnumerationHandler>emptyList() : customHandlers;
}
@Override
@@ -451,6 +451,25 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
int psiEndOffset = textBlock.getPsiEndOffset();
endOffset = psiEndOffset;
lengthShift = textBlock.getTextEndOffset() - psiEndOffset;
if (oldText != null) {
String psiPrefix = oldText.substring(0, startOffset);
String docPrefix = chars.subSequence(0, startOffset).toString();
String psiSuffix = oldText.substring(psiEndOffset);
String docSuffix = chars.subSequence(textBlock.getTextEndOffset(), chars.length()).toString();
if (!psiPrefix.equals(docPrefix) || !psiSuffix.equals(docSuffix)) {
String msg = "PSI/document inconsistency before reparse: ";
if (!psiPrefix.equals(docPrefix)) {
msg = msg + "psiPrefix=" + psiPrefix + "; docPrefix=" + docPrefix + ";";
}
if (!psiSuffix.equals(docSuffix)) {
msg = msg + "psiSuffix=" + psiSuffix + "; docSuffix=" + docSuffix + ";";
}
throw new AssertionError(msg);
}
} else if (document.getTextLength() - textBlock.getTextEndOffset() != file.getTextLength() - psiEndOffset) {
throw new AssertionError("PSI/document inconsistency before reparse: file=" + file);
}
}
else {
startOffset = 0;
@@ -24,8 +24,8 @@ import com.intellij.psi.PsiFile;
import com.intellij.util.messages.Topic;
public interface PsiDocumentTransactionListener {
Topic<PsiDocumentTransactionListener> TOPIC = new Topic("psi.DocumentTransactionListener", PsiDocumentTransactionListener.class, Topic.BroadcastDirection.TO_PARENT);
Topic<PsiDocumentTransactionListener> TOPIC = new Topic<PsiDocumentTransactionListener>("psi.DocumentTransactionListener", PsiDocumentTransactionListener.class, Topic.BroadcastDirection.TO_PARENT);
void transactionStarted(Document doc, PsiFile file);
void transactionCompleted(Document doc, PsiFile file);
}
}
@@ -56,7 +56,12 @@ public class DummyHolder extends PsiFileImpl {
((DummyHolderViewProvider)getViewProvider()).setDummyHolder(this);
myContext = context;
myTable = table != null ? table : IdentityCharTable.INSTANCE;
if(contentElement != null) {
if (contentElement instanceof FileElement) {
myFileElement = (FileElement)contentElement;
myFileElement.setPsi(this);
if (myTable != null) myFileElement.setCharTable(myTable);
}
else if (contentElement != null) {
getTreeElement().rawAddChildren(contentElement);
clearCaches();
}
@@ -81,7 +86,7 @@ public class DummyHolder extends PsiFileImpl {
}
public boolean isValid() {
if(myExplicitlyValid != null) return myExplicitlyValid.booleanValue();
if (myExplicitlyValid != null) return myExplicitlyValid.booleanValue();
return super.isValid() && !(myContext != null && !myContext.isValid());
}
@@ -112,10 +117,10 @@ public class DummyHolder extends PsiFileImpl {
}
public FileElement getTreeElementNoLock() {
if(myFileElement == null){
if (myFileElement == null) {
myFileElement = new FileElement(TokenType.DUMMY_HOLDER, null);
myFileElement.setPsi(this);
if(myTable != null) myFileElement.setCharTable(myTable);
if (myTable != null) myFileElement.setCharTable(myTable);
clearCaches();
}
return myFileElement;
@@ -909,24 +909,30 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
}
private void bindStubs(final ASTNode tree, final Iterator<StubElement<?>> stubs, final StubBuilder builder) {
final IElementType type = tree.getElementType();
((TreeElement)tree).acceptTree(new RecursiveTreeElementWalkingVisitor() {
@Override
protected void visitNode(TreeElement root) {
CompositeElement parent = root.getTreeParent();
IElementType parentType = parent == null ? null : parent.getElementType();
final IElementType type = root.getElementType();
if (parentType != null && builder.skipChildProcessingWhenBuildingStubs(parentType, type)) {
return;
}
if (type instanceof IStubElementType && ((IStubElementType) type).shouldCreateStub(tree)) {
final StubElement stub = stubs.hasNext() ? stubs.next() : null;
if (stub == null || stub.getStubType() != tree.getElementType()) {
rebuildStub();
assert false : "Stub and PSI element type mismatch in " + getName() + ": stub:" + stub + ", AST:" + tree.getElementType();
if (type instanceof IStubElementType && ((IStubElementType) type).shouldCreateStub(root)) {
final StubElement stub = stubs.hasNext() ? stubs.next() : null;
if (stub == null || stub.getStubType() != type) {
rebuildStub();
assert false : "Stub and PSI element type mismatch in " + getName() + ": stub:" + stub + ", AST:" + type;
}
//noinspection unchecked
((StubBase)stub).setPsi(root.getPsi());
}
super.visitNode(root);
}
//noinspection unchecked
((StubBase)stub).setPsi(tree.getPsi());
}
for (ASTNode node : tree.getChildren(null)) {
if (!builder.skipChildProcessingWhenBuildingStubs(type, node.getElementType())) {
bindStubs(node, stubs, builder);
}
}
});
}
private void rebuildStub() {
@@ -23,20 +23,21 @@ import com.intellij.psi.impl.source.tree.TreeElement;
import org.jetbrains.annotations.Nullable;
public class SourceTreeToPsiMap {
private SourceTreeToPsiMap() {
}
private SourceTreeToPsiMap() { }
public static PsiElement treeElementToPsi(@Nullable ASTNode element) {
@Nullable
public static PsiElement treeElementToPsi(@Nullable final ASTNode element) {
if (element == null) return null;
return element.getPsi();
}
public static ASTNode psiElementToTree(@Nullable PsiElement psiElement) {
@Nullable
public static ASTNode psiElementToTree(@Nullable final PsiElement psiElement) {
if (psiElement == null) return null;
return psiElement.getNode();
}
public static boolean hasTreeElement(@Nullable PsiElement psiElement) {
public static boolean hasTreeElement(@Nullable final PsiElement psiElement) {
return psiElement instanceof TreeElement || psiElement instanceof ASTDelegatePsiElement || psiElement instanceof PsiFileImpl;
}
}
@@ -23,6 +23,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.tree.events.ChangeInfo;
import com.intellij.pom.tree.events.TreeChangeEvent;
import com.intellij.pom.tree.events.impl.ChangeInfoImpl;
@@ -388,7 +389,8 @@ public class CompositeElement extends TreeElement {
}
catch (AssertionError e) {
myCachedLength = NOT_CACHED;
LOG.error("===\n"+PerformanceWatcher.dumpThreadsToString()+"\n===\n", e);
String assertion = StringUtil.getThrowableText(e);
LOG.error("Walking failure: ===\n"+assertion+"\n=== Thread dump:\n"+PerformanceWatcher.dumpThreadsToString()+"\n===\n");
}
return myCachedLength;
}
@@ -60,10 +60,9 @@ public class InjectedLanguageUtil {
});
}
private static PsiElement loadTree(PsiElement host) {
PsiFile file = host.getContainingFile();
if (file instanceof DummyHolder) {
PsiElement context = file.getContext();
private static PsiElement loadTree(PsiElement host, PsiFile containingFile) {
if (containingFile instanceof DummyHolder) {
PsiElement context = containingFile.getContext();
if (context != null) {
PsiFile topFile = context.getContainingFile();
topFile.getNode(); //load tree
@@ -81,7 +80,7 @@ public class InjectedLanguageUtil {
@Nullable
public static List<Pair<PsiElement, TextRange>> getInjectedPsiFiles(@NotNull final PsiElement host) {
final PsiElement inTree = loadTree(host);
final PsiElement inTree = loadTree(host, host.getContainingFile());
final List<Pair<PsiElement, TextRange>> result = new SmartList<Pair<PsiElement, TextRange>>();
enumerate(inTree, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
public void visit(@NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) {
@@ -125,7 +124,7 @@ public class InjectedLanguageUtil {
if (file == null || !file.isPhysical() && file.getOriginalFile() == file) return;
}
PsiElement inTree = loadTree(host);
PsiElement inTree = loadTree(host, containingFile);
if (inTree != host) {
host = inTree;
containingFile = host.getContainingFile();
@@ -53,4 +53,6 @@ public interface FoldRegion extends RangeMarker {
@Nullable
FoldingGroup getGroup();
boolean shouldNeverExpand();
}
@@ -377,7 +377,7 @@ public class HintManagerImpl extends HintManager implements Disposable {
Dimension size = hint.getComponent().getPreferredSize();
if (hint.isRealPopup()) {
final Point editorCorner = editor.getContentComponent().getLocation();
final Point editorCorner = editor.getComponent().getLocation();
SwingUtilities.convertPointToScreen(editorCorner, layeredPane);
final Rectangle editorScreen = ScreenUtil.getScreenRectangle(editorCorner.x, editorCorner.y);
@@ -0,0 +1,45 @@
/*
* Copyright 2000-2010 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.ide.plugins;
import com.intellij.openapi.project.Project;
import com.intellij.statistic.UsagesCollector;
import com.intellij.statistic.beans.GroupDescriptor;
import com.intellij.statistic.beans.UsageDescriptor;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
public class PluginsUsagesCollector extends UsagesCollector {
private static final String GROUP_ID = "plugins";
public static GroupDescriptor getGroupId() {
return GroupDescriptor.create(GROUP_ID, GroupDescriptor.HIGHER_PRIORITY);
}
@NotNull
public Set<UsageDescriptor> getUsages(@Nullable Project project) {
return ContainerUtil.map2Set(PluginManager.getPlugins(), new Function<IdeaPluginDescriptor, UsageDescriptor>() {
@Override
public UsageDescriptor fun(IdeaPluginDescriptor descriptor) {
return new UsageDescriptor(getGroupId(), descriptor.getName(), 1);
}
});
}
}
@@ -1196,4 +1196,9 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
return false;
}
@Override
public String toString() {
return "Application";
}
}
@@ -59,7 +59,7 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap
private static final int COMMAND_TO_RUN_COMPACT = 20;
private static final int FREE_QUEUES_LIMIT = 30;
private final ProjectEx myProject;
@Nullable private final ProjectEx myProject;
private final CommandProcessor myCommandProcessor;
private final StartupManager myStartupManager;
@@ -110,6 +110,7 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap
return "UndoManager";
}
@Nullable
public Project getProject() {
return myProject;
}
@@ -337,7 +338,9 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap
Runnable executeUndoOrRedoAction = new Runnable() {
public void run() {
try {
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
if (myProject != null) {
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
}
myMerger.undoOrRedo(editor, isUndo);
}
catch (RuntimeException ex) {
@@ -83,8 +83,16 @@ public class BackspaceAction extends EditorAction {
int offset = editor.getCaretModel().getOffset();
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
editor.getSelectionModel().removeSelection();
document.deleteString(offset-1, offset);
editor.getCaretModel().moveToOffset(offset - 1, true);
FoldRegion region = editor.getFoldingModel().getCollapsedRegionAtOffset(offset - 1);
if (region != null && region.shouldNeverExpand()) {
document.deleteString(region.getStartOffset(), region.getEndOffset());
editor.getCaretModel().moveToOffset(region.getStartOffset());
}
else {
document.deleteString(offset - 1, offset);
editor.getCaretModel().moveToOffset(offset - 1, true);
}
}
}
else if(lineNumber > 0) {
@@ -96,12 +96,19 @@ public class DeleteAction extends EditorAction {
Document document = editor.getDocument();
if(afterLineEnd < 0) {
int offset = editor.getCaretModel().getOffset();
document.deleteString(offset, offset + 1);
editor.getCaretModel().moveToOffset(offset);
FoldRegion region = editor.getFoldingModel().getCollapsedRegionAtOffset(offset);
if (region != null && region.shouldNeverExpand()) {
document.deleteString(region.getStartOffset(), region.getEndOffset());
editor.getCaretModel().moveToOffset(region.getStartOffset());
}
else {
document.deleteString(offset, offset + 1);
editor.getCaretModel().moveToOffset(offset);
}
return;
}
if(lineNumber + 1 >= document.getLineCount())
return;
if(lineNumber + 1 >= document.getLineCount()) return;
// Do not group delete newline and other deletions.
CommandProcessor commandProcessor = CommandProcessor.getInstance();
@@ -44,7 +44,7 @@ public interface FoldingModelEx extends FoldingModel {
FoldRegion[] fetchTopLevel();
@Nullable
FoldRegion createFoldRegion(int startOffset, int endOffset, @NotNull String placeholder, FoldingGroup group);
FoldRegion createFoldRegion(int startOffset, int endOffset, @NotNull String placeholder, FoldingGroup group, boolean neverExpands);
boolean addListener(@NotNull FoldingListener listener);
@@ -32,8 +32,8 @@ public class EditorDocumentPriorities {
*/
public static final int RANGE_MARKER = 40;
public static final int SOFT_WRAP_MODEL = 60;
public static final int FOLD_MODEL = 80;
public static final int FOLD_MODEL = 60;
public static final int SOFT_WRAP_MODEL = 80;
public static final int LEXER_EDITOR = 100;
public static final int CARET_MODEL = 120;
public static final int SELECTION_MODEL = 140;
@@ -2356,7 +2356,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (i < softWrapChars.length - 1) {
position.x = 0; // Soft wrap starts new visual line
position.x = drawString(
g, softWrapChars, i + 1, softWrapChars.length, position, clip, effectColor, effectType, fontType, fontColor
g, softWrapChars, i + 1, softWrapChars.length, position, clip, null, null, fontType, fontColor
);
}
position.x += mySoftWrapModel.paint(g, SoftWrapDrawingType.AFTER_SOFT_WRAP, position.x, position.y, getLineHeight());
@@ -2367,7 +2367,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
// Draw token text before the wrap.
if (softWrap.getStart() > startToUse) {
position.x = drawString(
g, text, startToUse, softWrap.getStart(), position, clip, effectColor, effectType, fontType, fontColor
g, text, startToUse, softWrap.getStart(), position, clip, null, null, fontType, fontColor
);
}
@@ -2385,7 +2385,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
// Draw soft wrap symbols on current visual line if any.
if (i - softWrapSegmentStartIndex > 0) {
drawString(
g, softWrapChars, softWrapSegmentStartIndex, i, position, clip, effectColor, effectType, fontType, fontColor
g, softWrapChars, softWrapSegmentStartIndex, i, position, clip, null, null, fontType, fontColor
);
}
mySoftWrapModel.paint(g, SoftWrapDrawingType.BEFORE_SOFT_WRAP_LINE_FEED, position.x, position.y, getLineHeight());
@@ -2405,8 +2405,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
// Draw remaining soft wrap symbols from its last line if any.
if (softWrapSegmentStartIndex < softWrapChars.length) {
position.x += drawString(
g, softWrapChars, softWrapSegmentStartIndex, softWrapChars.length, position, clip, effectColor, effectType,
fontType, fontColor
g, softWrapChars, softWrapSegmentStartIndex, softWrapChars.length, position, clip, null, null, fontType, fontColor
);
}
position.x += mySoftWrapModel.paint(g, SoftWrapDrawingType.AFTER_SOFT_WRAP, position.x, position.y, getLineHeight());
@@ -36,10 +36,17 @@ public class FoldRegionImpl extends RangeMarkerImpl implements FoldRegion {
private final Editor myEditor;
private final String myPlaceholderText;
private final FoldingGroup myGroup;
private final boolean myShouldNeverExpand;
FoldRegionImpl(@NotNull Editor editor, int startOffset, int endOffset, @NotNull String placeholder, FoldingGroup group) {
FoldRegionImpl(@NotNull Editor editor,
int startOffset,
int endOffset,
@NotNull String placeholder,
FoldingGroup group,
boolean shouldNeverExpand) {
super((DocumentEx)editor.getDocument(), startOffset, endOffset);
myGroup = group;
myShouldNeverExpand = shouldNeverExpand;
myIsExpanded = true;
myEditor = editor;
myPlaceholderText = placeholder;
@@ -91,6 +98,11 @@ public class FoldRegionImpl extends RangeMarkerImpl implements FoldRegion {
return myGroup;
}
@Override
public boolean shouldNeverExpand() {
return myShouldNeverExpand;
}
public String toString() {
return "FoldRegion " + (isExpanded() ? "-" : "+") +
"(" + getStartOffset() + ":" + getEndOffset() + ")" + (isValid() ? "" : "(invalid)");
@@ -142,7 +142,7 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList
}
public FoldRegion addFoldRegion(int startOffset, int endOffset, @NotNull String placeholderText) {
FoldRegion region = createFoldRegion(startOffset, endOffset, placeholderText, null);
FoldRegion region = createFoldRegion(startOffset, endOffset, placeholderText, null, false);
if (region == null) return null;
if (!addFoldRegion(region)) {
region.dispose();
@@ -167,9 +167,9 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList
final FoldingGroup group = region.getGroup();
if (group != null) {
myGroups.putValue(group, region);
for (FoldingListener listener : myListeners) {
listener.onFoldRegionStateChange(region);
}
}
for (FoldingListener listener : myListeners) {
listener.onFoldRegionStateChange(region);
}
return true;
}
@@ -267,7 +267,7 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList
public void expandFoldRegion(FoldRegion region) {
assertIsDispatchThread();
if (region.isExpanded()) return;
if (region.isExpanded() || region.shouldNeverExpand()) return;
if (!myIsBatchFoldingProcessing) {
LOG.error("Fold regions must be collapsed or expanded inside batchFoldProcessing() only.");
@@ -456,8 +456,8 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList
return EditorDocumentPriorities.FOLD_MODEL;
}
public FoldRegion createFoldRegion(int startOffset, int endOffset, @NotNull String placeholder, FoldingGroup group) {
FoldRegionImpl region = new FoldRegionImpl(myEditor, startOffset, endOffset, placeholder, group);
public FoldRegion createFoldRegion(int startOffset, int endOffset, @NotNull String placeholder, FoldingGroup group, boolean neverExpands) {
FoldRegionImpl region = new FoldRegionImpl(myEditor, startOffset, endOffset, placeholder, group, neverExpands);
region.registerInDocument();
LOG.assertTrue(region.isValid());
return region;
@@ -76,6 +76,17 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
private int myActive;
private boolean myUseSoftWraps;
/**
* Soft wraps need to be kept up-to-date on all editor modification (changing text, adding/removing/expanding/collapsing fold
* regions etc). Hence, we need to react to all types of target changes. However, soft wraps processing uses various information
* provided by editor and there is a possible case that that information is inconsistent during update time (e.g. fold model
* advances fold region offsets when end-user types before it, hence, fold regions data is inconsistent between the moment
* when text changes are applied to the document and fold data is actually updated).
* <p/>
* Current field serves as a flag that indicates if all preliminary actions necessary for successful soft wraps processing is done.
*/
private boolean myUpdateInProgress;
public SoftWrapModelImpl(@NotNull EditorEx editor) {
this(editor, new SoftWrapsStorage(), new CompositeSoftWrapPainter(editor));
}
@@ -271,7 +282,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
@NotNull
@Override
public LogicalPosition visualToLogicalPosition(@NotNull VisualPosition visual) {
if (!prepareToMapping()) {
if (myUpdateInProgress || !prepareToMapping()) {
return myEditor.visualToLogicalPosition(visual, false);
}
myActive++;
@@ -287,7 +298,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
@NotNull
@Override
public LogicalPosition offsetToLogicalPosition(int offset) {
if (!prepareToMapping()) {
if (myUpdateInProgress || !prepareToMapping()) {
return myEditor.offsetToLogicalPosition(offset, false);
}
myActive++;
@@ -302,7 +313,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
@NotNull
public LogicalPosition adjustLogicalPosition(LogicalPosition defaultLogical, int offset) {
if (!prepareToMapping()) {
if (myUpdateInProgress || !prepareToMapping()) {
return defaultLogical;
}
@@ -318,7 +329,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
@NotNull
public VisualPosition adjustVisualPosition(@NotNull LogicalPosition logical, @NotNull VisualPosition defaultVisual) {
if (!prepareToMapping()) {
if (myUpdateInProgress || !prepareToMapping()) {
return defaultVisual;
}
@@ -477,6 +488,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
@Override
public void beforeDocumentChange(DocumentEvent event) {
myUpdateInProgress = true;
if (!isSoftWrappingEnabled()) {
return;
}
@@ -487,6 +499,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
@Override
public void documentChanged(DocumentEvent event) {
myUpdateInProgress = false;
if (!isSoftWrappingEnabled()) {
return;
}
@@ -497,6 +510,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
@Override
public void onFoldRegionStateChange(@NotNull FoldRegion region) {
myUpdateInProgress = true;
if (!isSoftWrappingEnabled() || !region.isValid()) {
return;
}
@@ -507,6 +521,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
@Override
public void onFoldProcessingEnd() {
myUpdateInProgress = false;
if (!isSoftWrappingEnabled()) {
return;
}
@@ -199,7 +199,7 @@ public class SoftWrapApplianceManager implements FoldingListener, DocumentListen
processNonFoldToken();
}
else {
boolean continueProcessing = processCollapsedFoldRegion(currentFold, event);
boolean continueProcessing = processCollapsedFoldRegion(currentFold);
if (!continueProcessing) {
return false;
}
@@ -224,11 +224,10 @@ public class SoftWrapApplianceManager implements FoldingListener, DocumentListen
* Encapsulates logic of processing given collapsed fold region.
*
* @param foldRegion target collapsed fold region to process
* @param event change event that triggered the processing
* @return <code>true</code> if processing should be continued; <code>false</code> otherwise
*/
private boolean processCollapsedFoldRegion(FoldRegion foldRegion, IncrementalCacheUpdateEvent event) {
if (processOutOfDateFoldRegion(foldRegion, event)) {
private boolean processCollapsedFoldRegion(FoldRegion foldRegion) {
if (processOutOfDateFoldRegion(foldRegion)) {
return false;
}
@@ -298,11 +297,10 @@ public class SoftWrapApplianceManager implements FoldingListener, DocumentListen
* This method encapsulates logic for checking and reacting on such a situation.
*
* @param foldRegion fold region that may be out-of-date
* @param event change event that triggered the processing
* @return <code>true</code> if given fold region is really out-of-date and processing should be stopped;
* <code>false</code> otherwise;
*/
private boolean processOutOfDateFoldRegion(FoldRegion foldRegion, IncrementalCacheUpdateEvent event) {
private boolean processOutOfDateFoldRegion(FoldRegion foldRegion) {
Document document = myEditor.getDocument();
@@ -310,17 +308,11 @@ public class SoftWrapApplianceManager implements FoldingListener, DocumentListen
// case that offsets of the trailing fold regions should be updated as well.
IncrementalCacheUpdateEvent newEvent = new IncrementalCacheUpdateEvent(document);
// We assume here that fold model is processed after soft wrap (as it needs to perform document dimensions mapping).
// So, there is a possible case that user performed modifications at particular fold region but fold model is not updated yet
// and IterationState returns valid fold region. Hence, we introduce a dedicated check here.
if (!foldRegion.isValid() || (event.getExactOffsetsDiff() != 0 && foldRegion.getStartOffset() < event.getOldExactEndOffset()
&& foldRegion.getEndOffset() > event.getOldExactStartOffset()) || myContext.tokenStartOffset != foldRegion.getStartOffset())
{
if (!foldRegion.isValid() || myContext.tokenStartOffset != foldRegion.getStartOffset()) {
myEventsStorage.add(document, newEvent);
return true;
}
if (foldRegion.getEndOffset() <= document.getTextLength()) {
return false;
}
@@ -220,6 +220,7 @@ public class ProjectImpl extends ComponentManagerImpl implements ProjectEx {
@Nullable
@NonNls
public String getLocation() {
if (myName == null) return null; // was called before initialized
return isDisposed() ? null : getStateStore().getLocation();
}
@@ -354,6 +354,8 @@ public final class UpdateChecker {
}
catch (Exception ignored) {
}
catch (InternalError ignored) {
}
propertiesComponent.setValue(INSTALLATION_UID, uid);
}
else {
@@ -565,10 +565,12 @@ public abstract class LocalFileSystemBase extends LocalFileSystem {
if (parentFile != null) {
// I hope ls works fast on Unix
final String[] canonicalFileNames = parentFile.list();
for (String name : canonicalFileNames) {
// if names are equals
if (name.compareToIgnoreCase(originalFileName) == 0) {
return name;
if (canonicalFileNames != null) {
for (String name : canonicalFileNames) {
// if names are equals
if (name.compareToIgnoreCase(originalFileName) == 0) {
return name;
}
}
}
}
@@ -20,6 +20,9 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
/**
* @see #hide()
*/
public interface Hint {
/**
* @param parentComponent defines coordinate system where hint will be shown.
@@ -36,6 +39,13 @@ public interface Hint {
*/
boolean isVisible();
/**
* Hides current hint object.
* <p/>
* <b>Note:</b> this method is also used as a destruction callback, i.e. it performs necessary de-initialization when
* current hint is not necessary to use anymore. Hence, it's <b>necessary</b> to call it from place where you definitely
* now that current hint will not be used.
*/
void hide();
void addHintListener(HintListener listener);
@@ -1081,6 +1081,8 @@ goto.inspection.action.text=&Run Inspection by Name...
label.no.inspections.found=No inspections found
#Scripting library management
scripting.lib.name=&Name
scripting.lib.file.title=Files
scripting.lib.file.location=Location
scripting.lib.file.type=Type
scripting.lib.select.root=Select library file or directory
@@ -1090,6 +1092,9 @@ scripting.lib.detach=&Detach
scripting.lib.add=&Add...
scripting.lib.edit=&Edit...
scripting.lib.remove=&Remove
scripting.lib.docUrl.specify=&Specify...
scripting.lib.docUrl.remove=&Remove
scripting.lib.docUrl.title=Documentation URLs
scripting.lib.usageScope=Usage Scope
scripting.lib.usageScope.caption=Specify which libraries are used in specific files and/or directories.
scripting.lib.usageScope.tableTitle=Library
@@ -204,5 +204,6 @@
<bundledKeymapProvider implementation="com.intellij.openapi.keymap.impl.DefaultBundledKeymaps"/>
<!-- <checkinHandlerFactory implementation="com.intellij.openapi.vcs.CheckRemoteStatusCheckinHandlerFactory"/> -->
<statistics.usagesCollector implementation="com.intellij.ide.plugins.PluginsUsagesCollector"/>
<statistics.usagesCollector implementation="com.intellij.featureStatistics.FeaturesUsageCollector"/>
</extensions>
@@ -67,6 +67,11 @@ public class MockFoldRegion extends UserDataHolderBase implements FoldRegion {
throw new UnsupportedOperationException("FoldRegion.getGroup() is not implemented yet at " + getClass());
}
@Override
public boolean shouldNeverExpand() {
return false;
}
@NotNull
@Override
public Document getDocument() {
@@ -19,8 +19,7 @@ import org.apache.log4j.Logger;
import org.jetbrains.annotations.NonNls;
@NonNls public abstract class LoggedErrorProcessor {
private final static LoggedErrorProcessor DEFAULT = new LoggedErrorProcessor() {
private static final LoggedErrorProcessor DEFAULT = new LoggedErrorProcessor() {
@Override
public void processError(String message, Throwable t, String[] details, Logger logger) {
logger.info(message, t);
@@ -28,8 +27,8 @@ import org.jetbrains.annotations.NonNls;
t.printStackTrace();
if (details != null && details.length > 0) {
System.out.println("details: ");
for (int i = 0; i < details.length; i++) {
System.out.println(details[i]);
for (String detail : details) {
System.out.println(detail);
}
}
@@ -795,7 +795,7 @@ public class StringUtil {
@NotNull
public static String trimEnd(@NotNull String s, @NonNls @NotNull String suffix) {
if (s.endsWith(suffix)) {
return s.substring(0, s.lastIndexOf(suffix));
return s.substring(0, s.length() - suffix.length());
}
return s;
}
@@ -1087,6 +1087,22 @@ public class StringUtil {
return result.toString();
}
@NotNull
public static String join(final String... strings) {
if (strings == null || strings.length == 0) return "";
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
for (final String string : strings) {
builder.append(string);
}
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
@NotNull
public static String stripQuotesAroundValue(@NotNull String text) {
if (startsWithChar(text, '\"') || startsWithChar(text, '\'')) text = text.substring(1);
@@ -47,25 +47,18 @@ public class MessageBusConnectionImpl implements MessageBusConnection {
}
public <L> void subscribe(Topic<L> topic, L handler) {
if (mySubscriptions.containsKey(topic)) {
if (mySubscriptions.put(topic, handler) != null) {
throw new IllegalStateException("Subscription to " + topic + " already exists");
}
mySubscriptions.put(topic, handler);
myBus.notifyOnSubscription(this, topic);
}
public <L> void subscribe(Topic<L> topic) {
if (mySubscriptions.containsKey(topic)) {
throw new IllegalStateException("Subscription to " + topic + " already exists");
}
if (myDefaultHandler == null) {
throw new IllegalStateException("Connection must have default handler installed prior to any anonymous subscriptions.");
}
mySubscriptions.put(topic, myDefaultHandler);
myBus.notifyOnSubscription(this, topic);
subscribe(topic, (L)myDefaultHandler);
}
public void setDefaultHandler(MessageHandler handler) {

Some files were not shown because too many files have changed in this diff Show More