blob: 0515b4983ce27fc90052087ca778565d1f868231 [file] [log] [blame]
/*
* Copyright 2000-2014 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;
import com.intellij.lang.*;
import com.intellij.lang.java.lexer.JavaLexer;
import com.intellij.lang.java.parser.JavaParser;
import com.intellij.lang.java.parser.JavaParserUtil;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.project.Project;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleSettingsFacade;
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.FileElement;
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.containers.ConcurrentHashMap;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements PsiElementFactory {
private PsiClass myArrayClass;
private PsiClass myArrayClass15;
private final ConcurrentHashMap<GlobalSearchScope, PsiClassType> myCachedObjectType = new ConcurrentHashMap<GlobalSearchScope, PsiClassType>();
public PsiElementFactoryImpl(final PsiManagerEx manager) {
super(manager);
manager.registerRunnableToRunOnChange(new Runnable() {
@Override
public void run() {
myCachedObjectType.clear();
}
});
}
@NotNull
@Override
public PsiClass getArrayClass(@NotNull final LanguageLevel languageLevel) {
if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_5)) {
if (myArrayClass == null) {
@NonNls final String body = "public class __Array__{\n public final int length;\n public Object clone() {}\n}";
myArrayClass = ((PsiExtensibleClass)createClassFromText(body, null)).getOwnInnerClasses().get(0);
}
return myArrayClass;
}
else {
if (myArrayClass15 == null) {
@NonNls final String body = "public class __Array__<T>{\n public final int length;\n public T[] clone() {}\n}";
myArrayClass15 = ((PsiExtensibleClass)createClassFromText(body, null)).getOwnInnerClasses().get(0);
}
return myArrayClass15;
}
}
@NotNull
@Override
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;
if (typeParameters.length == 1) {
substitutor = substitutor.put(typeParameters[0], componentType);
}
return createType(arrayClass, substitutor);
}
@NotNull
@Override
public PsiClassType createType(@NotNull PsiClass resolve, @NotNull PsiSubstitutor substitutor) {
return new PsiImmediateClassType(resolve, substitutor);
}
@NotNull
@Override
public PsiClassType createType(@NotNull PsiClass resolve, @NotNull PsiSubstitutor substitutor, @Nullable LanguageLevel languageLevel) {
return new PsiImmediateClassType(resolve, substitutor, languageLevel);
}
@NotNull
@Override
public PsiClassType createType(@NotNull PsiClass resolve,
@NotNull PsiSubstitutor substitutor,
@Nullable LanguageLevel languageLevel,
@NotNull PsiAnnotation[] annotations) {
return new PsiImmediateClassType(resolve, substitutor, languageLevel, annotations);
}
@NotNull
@Override
public PsiClass createClass(@NotNull final String name) throws IncorrectOperationException {
return createClassInner("class", name);
}
@NotNull
@Override
public PsiClass createInterface(@NotNull final String name) throws IncorrectOperationException {
return createClassInner("interface", name);
}
@NotNull
@Override
public PsiClass createEnum(@NotNull final String name) throws IncorrectOperationException {
return createClassInner("enum", name);
}
@NotNull
@Override
public PsiClass createAnnotationType(@NotNull @NonNls String name) throws IncorrectOperationException {
return createClassInner("@interface", name);
}
private PsiClass createClassInner(@NonNls final String type, @NonNls String name) {
PsiUtil.checkIsIdentifier(myManager, name);
final PsiJavaFile aFile = createDummyJavaFile("public " + type + " " + name + " { }");
final PsiClass[] classes = aFile.getClasses();
if (classes.length != 1) {
throw new IncorrectOperationException("Incorrect " + type + " name \"" + name + "\".");
}
return classes[0];
}
@NotNull
@Override
public PsiTypeElement createTypeElement(@NotNull final PsiType psiType) {
final LightTypeElement element = new LightTypeElement(myManager, psiType);
CodeEditUtil.setNodeGenerated(element.getNode(), true);
return element;
}
@NotNull
@Override
public PsiJavaCodeReferenceElement createReferenceElementByType(@NotNull final PsiClassType type) {
if (type instanceof PsiClassReferenceType) {
return ((PsiClassReferenceType)type).getReference();
}
final PsiClassType.ClassResolveResult resolveResult = type.resolveGenerics();
final PsiClass refClass = resolveResult.getElement();
assert refClass != null : type;
return new LightClassReference(myManager, type.getCanonicalText(true), refClass, resolveResult.getSubstitutor());
}
@NotNull
@Override
public PsiTypeParameterList createTypeParameterList() {
final PsiTypeParameterList parameterList = createMethodFromText("void foo()", null).getTypeParameterList();
assert parameterList != null;
return parameterList;
}
@NotNull
@Override
public PsiTypeParameter createTypeParameter(String name, PsiClassType[] superTypes) {
@NonNls StringBuilder builder = new StringBuilder();
builder.append("public <").append(name);
if (superTypes.length > 1 ||
superTypes.length == 1 && !superTypes[0].equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
builder.append(" extends ");
for (PsiClassType type : superTypes) {
if (type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) continue;
builder.append(type.getCanonicalText(true)).append('&');
}
builder.delete(builder.length() - 1, builder.length());
}
builder.append("> void foo(){}");
try {
return createMethodFromText(builder.toString(), null).getTypeParameters()[0];
}
catch (RuntimeException e) {
throw new IncorrectOperationException("type parameter text: " + builder.toString());
}
}
@NotNull
@Override
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\".");
}
@NonNls final String text = "class _Dummy_ { private " + type.getCanonicalText(true) + " " + name + "; }";
final PsiJavaFile aFile = createDummyJavaFile(text);
final PsiClass[] classes = aFile.getClasses();
if (classes.length < 1) {
throw new IncorrectOperationException("Class was not created " + text);
}
final PsiClass psiClass = classes[0];
final PsiField[] fields = psiClass.getFields();
if (fields.length < 1) {
throw new IncorrectOperationException("Field was not created " + text);
}
PsiField field = fields[0];
field = (PsiField)JavaCodeStyleManager.getInstance(myManager.getProject()).shortenClassReferences(field);
return (PsiField)CodeStyleManager.getInstance(myManager.getProject()).reformat(field);
}
@NotNull
@Override
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 method with type \"null\".");
}
final String canonicalText = returnType.getCanonicalText(true);
final PsiJavaFile aFile = createDummyJavaFile("class _Dummy_ { public " + canonicalText + " " + name + "() {} }");
final PsiClass[] classes = aFile.getClasses();
if (classes.length < 1) {
throw new IncorrectOperationException("Class was not created. Method name: " + name + "; return type: " + canonicalText);
}
final PsiMethod[] methods = classes[0].getMethods();
if (methods.length < 1) {
throw new IncorrectOperationException("Method was not created. Method name: " + name + "; return type: " + canonicalText);
}
PsiMethod method = methods[0];
method = (PsiMethod)JavaCodeStyleManager.getInstance(myManager.getProject()).shortenClassReferences(method);
return (PsiMethod)CodeStyleManager.getInstance(myManager.getProject()).reformat(method);
}
@NotNull
@Override
public PsiMethod createConstructor() {
return createConstructor("_Dummy_");
}
@NotNull
@Override
public PsiMethod createConstructor(@NotNull @NonNls final String name) {
final PsiJavaFile aFile = createDummyJavaFile("class " + name + " { public " + name + "() {} }");
final PsiMethod method = aFile.getClasses()[0].getMethods()[0];
return (PsiMethod)CodeStyleManager.getInstance(myManager.getProject()).reformat(method);
}
@Override
public PsiMethod createConstructor(@NotNull @NonNls String name, PsiElement context) {
return createMethodFromText(name + "() {}", context);
}
@NotNull
@Override
public PsiClassInitializer createClassInitializer() throws IncorrectOperationException {
final PsiJavaFile aFile = createDummyJavaFile("class _Dummy_ { {} }");
final PsiClassInitializer classInitializer = aFile.getClasses()[0].getInitializers()[0];
return (PsiClassInitializer)CodeStyleManager.getInstance(myManager.getProject()).reformat(classInitializer);
}
@NotNull
@Override
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 parameter with type \"null\".");
}
final String text = type.getCanonicalText(true) + " " + name;
PsiParameter parameter = createParameterFromText(text, null);
final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myManager.getProject());
PsiUtil.setModifierProperty(parameter, PsiModifier.FINAL,
JavaCodeStyleSettingsFacade.getInstance(myManager.getProject()).isGenerateFinalParameters());
GeneratedMarkerVisitor.markGenerated(parameter);
parameter = (PsiParameter)JavaCodeStyleManager.getInstance(myManager.getProject()).shortenClassReferences(parameter);
return (PsiParameter)codeStyleManager.reformat(parameter);
}
@Override
public PsiParameter createParameter(@NotNull @NonNls String name, PsiType type, PsiElement context) throws IncorrectOperationException {
final PsiMethod psiMethod = createMethodFromText("void f(" + type.getCanonicalText(true) + " " + name + ") {}", context);
final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
return parameters[0];
}
@NotNull
@Override
public PsiCodeBlock createCodeBlock() {
final PsiCodeBlock block = createCodeBlockFromText("{}", null);
return (PsiCodeBlock)CodeStyleManager.getInstance(myManager.getProject()).reformat(block);
}
@NotNull
@Override
public PsiClassType createType(@NotNull final PsiClass aClass) {
return new PsiImmediateClassType(aClass, aClass instanceof PsiTypeParameter ? PsiSubstitutor.EMPTY : createRawSubstitutor(aClass));
}
@NotNull
@Override
public PsiClassType createType(@NotNull final PsiJavaCodeReferenceElement classReference) {
return new PsiClassReferenceType(classReference, null);
}
@NotNull
@Override
public PsiClassType createType(@NotNull final PsiClass aClass, final PsiType parameter) {
final PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
assert typeParameters.length == 1 : aClass;
return createType(aClass, PsiSubstitutor.EMPTY.put(typeParameters[0], parameter));
}
@NotNull
@Override
public PsiClassType createType(@NotNull final PsiClass aClass, final PsiType... parameters) {
return createType(aClass, PsiSubstitutor.EMPTY.putAll(aClass, parameters));
}
@NotNull
@Override
public PsiSubstitutor createRawSubstitutor(@NotNull final PsiTypeParameterListOwner owner) {
Map<PsiTypeParameter, PsiType> substitutorMap = null;
for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(owner)) {
if (substitutorMap == null) substitutorMap = new HashMap<PsiTypeParameter, PsiType>();
substitutorMap.put(parameter, null);
}
return PsiSubstitutorImpl.createSubstitutor(substitutorMap);
}
@NotNull
@Override
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 PsiSubstitutorImpl.createSubstitutor(substitutorMap).putAll(baseSubstitutor);
}
@NotNull
@Override
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);
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);
final PsiElement psi = node.getPsi();
assert psi != null : text;
return psi;
}
@NotNull
@Override
public PsiSubstitutor createSubstitutor(@NotNull final Map<PsiTypeParameter, PsiType> map) {
return PsiSubstitutorImpl.createSubstitutor(map);
}
@Nullable
@Override
public PsiPrimitiveType createPrimitiveType(@NotNull final String text) {
return PsiJavaParserFacadeImpl.getPrimitiveType(text);
}
@NotNull
@Override
public PsiClassType createTypeByFQClassName(@NotNull final String qName) {
return createTypeByFQClassName(qName, GlobalSearchScope.allScope(myManager.getProject()));
}
@NotNull
@Override
public PsiClassType createTypeByFQClassName(@NotNull final String qName, @NotNull final GlobalSearchScope resolveScope) {
if (CommonClassNames.JAVA_LANG_OBJECT.equals(qName)) {
PsiClassType cachedObjectType = myCachedObjectType.get(resolveScope);
if (cachedObjectType != null) {
return cachedObjectType;
}
PsiClass aClass = JavaPsiFacade.getInstance(myManager.getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, resolveScope);
if (aClass != null) {
cachedObjectType = new PsiImmediateClassType(aClass, PsiSubstitutor.EMPTY);
cachedObjectType = myCachedObjectType.cacheOrGet(resolveScope, cachedObjectType);
return cachedObjectType;
}
}
return new PsiClassReferenceType(createReferenceElementByFQClassName(qName, resolveScope), null);
}
@NotNull
@Override
public PsiJavaCodeReferenceElement createClassReferenceElement(@NotNull final PsiClass aClass) {
final String text;
if (aClass instanceof PsiAnonymousClass) {
text = ((PsiAnonymousClass)aClass).getBaseClassType().getPresentableText();
}
else {
text = aClass.getName();
}
return new LightClassReference(myManager, text, aClass);
}
@NotNull
@Override
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
@Override
public PsiJavaCodeReferenceElement createFQClassNameReferenceElement(@NotNull final String qName,
@NotNull final GlobalSearchScope resolveScope) {
return new LightClassReference(myManager, qName, qName, resolveScope);
}
@NotNull
@Override
public PsiJavaCodeReferenceElement createPackageReferenceElement(@NotNull final PsiPackage aPackage) throws IncorrectOperationException {
if (aPackage.getQualifiedName().isEmpty()) {
throw new IncorrectOperationException("Cannot create reference to default package.");
}
return new LightPackageReference(myManager, aPackage);
}
@NotNull
@Override
public PsiPackageStatement createPackageStatement(@NotNull final String name) throws IncorrectOperationException {
final PsiJavaFile aFile = createDummyJavaFile("package " + name + ";");
final PsiPackageStatement stmt = aFile.getPackageStatement();
if (stmt == null) {
throw new IncorrectOperationException("Incorrect package name: " + name);
}
return stmt;
}
@NotNull
@Override
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.");
}
final PsiJavaFile aFile = createDummyJavaFile("import static " + aClass.getQualifiedName() + "." + memberName + ";");
final PsiImportStatementBase statement = extractImport(aFile, true);
return (PsiImportStaticStatement)CodeStyleManager.getInstance(myManager.getProject()).reformat(statement);
}
@NotNull
@Override
public PsiParameterList createParameterList(@NotNull final String[] names, @NotNull final PsiType[] types) throws IncorrectOperationException {
@NonNls StringBuilder builder = new StringBuilder();
builder.append("void method(");
for (int i = 0; i < names.length; i++) {
if (i > 0) builder.append(", ");
builder.append(types[i].getCanonicalText(true)).append(' ').append(names[i]);
}
builder.append(");");
return createMethodFromText(builder.toString(), null).getParameterList();
}
@NotNull
@Override
public PsiReferenceList createReferenceList(@NotNull final PsiJavaCodeReferenceElement[] references) throws IncorrectOperationException {
@NonNls final StringBuilder builder = new StringBuilder();
builder.append("void method()");
if (references.length > 0){
builder.append(" throws ");
for (int i = 0; i < references.length; i++) {
if (i > 0) builder.append(", ");
builder.append(references[i].getCanonicalText());
}
}
builder.append(';');
return createMethodFromText(builder.toString(), null).getThrowsList();
}
@NotNull
@Override
public PsiJavaCodeReferenceElement createPackageReferenceElement(@NotNull final String packageName) throws IncorrectOperationException {
if (packageName.isEmpty()) {
throw new IncorrectOperationException("Cannot create reference to default package.");
}
return new LightPackageReference(myManager, packageName);
}
@NotNull
@Override
public PsiReferenceExpression createReferenceExpression(@NotNull final PsiClass aClass) throws IncorrectOperationException {
final String text;
if (aClass instanceof PsiAnonymousClass) {
text = ((PsiAnonymousClass)aClass).getBaseClassType().getPresentableText();
}
else {
text = aClass.getName();
}
return new LightClassReferenceExpression(myManager, text, aClass);
}
@NotNull
@Override
public PsiReferenceExpression createReferenceExpression(@NotNull final PsiPackage aPackage) throws IncorrectOperationException {
if (aPackage.getQualifiedName().isEmpty()) {
throw new IncorrectOperationException("Cannot create reference to default package.");
}
return new LightPackageReferenceExpression(myManager, aPackage);
}
@NotNull
@Override
public PsiIdentifier createIdentifier(@NotNull final String text) throws IncorrectOperationException {
PsiUtil.checkIsIdentifier(myManager, text);
return new LightIdentifier(myManager, text);
}
@NotNull
@Override
public PsiKeyword createKeyword(@NotNull final String text) throws IncorrectOperationException {
if (!PsiNameHelper.getInstance(myManager.getProject()).isKeyword(text)) {
throw new IncorrectOperationException("\"" + text + "\" is not a keyword.");
}
return new LightKeyword(myManager, text);
}
@NotNull
@Override
public PsiKeyword createKeyword(@NotNull @NonNls String keyword, PsiElement context) throws IncorrectOperationException {
if (!JavaLexer.isKeyword(keyword, PsiUtil.getLanguageLevel(context))) {
throw new IncorrectOperationException("\"" + keyword + "\" is not a keyword.");
}
return new LightKeyword(myManager, keyword);
}
@NotNull
@Override
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.");
}
final PsiJavaFile aFile = createDummyJavaFile("import " + aClass.getQualifiedName() + ";");
final PsiImportStatementBase statement = extractImport(aFile, false);
return (PsiImportStatement)CodeStyleManager.getInstance(myManager.getProject()).reformat(statement);
}
@NotNull
@Override
public PsiImportStatement createImportStatementOnDemand(@NotNull final String packageName) throws IncorrectOperationException {
if (packageName.isEmpty()) {
throw new IncorrectOperationException("Cannot create import statement for default package.");
}
if (!PsiNameHelper.getInstance(myManager.getProject()).isQualifiedName(packageName)) {
throw new IncorrectOperationException("Incorrect package name: \"" + packageName + "\".");
}
final PsiJavaFile aFile = createDummyJavaFile("import " + packageName + ".*;");
final PsiImportStatementBase statement = extractImport(aFile, false);
return (PsiImportStatement)CodeStyleManager.getInstance(myManager.getProject()).reformat(statement);
}
@NotNull
@Override
public PsiDeclarationStatement createVariableDeclarationStatement(@NotNull String name,
@NotNull PsiType type,
@Nullable PsiExpression initializer) throws IncorrectOperationException {
if (!isIdentifier(name)) {
throw new IncorrectOperationException("\"" + name + "\" is not an identifier.");
}
if (PsiType.NULL.equals(type)) {
throw new IncorrectOperationException("Cannot create variable with type \"null\".");
}
String text = "X " + name + (initializer != null ? " = x" : "") + ";";
PsiDeclarationStatement statement = (PsiDeclarationStatement)createStatementFromText(text, null);
PsiVariable variable = (PsiVariable)statement.getDeclaredElements()[0];
replace(variable.getTypeElement(), createTypeElement(type), text);
boolean generateFinalLocals = JavaCodeStyleSettingsFacade.getInstance(myManager.getProject()).isGenerateFinalLocals();
PsiUtil.setModifierProperty(variable, PsiModifier.FINAL, generateFinalLocals);
if (initializer != null) {
replace(variable.getInitializer(), initializer, text);
}
GeneratedMarkerVisitor.markGenerated(statement);
return statement;
}
private static void replace(@Nullable PsiElement original, @NotNull PsiElement replacement, @NotNull String message) {
assert original != null : message;
original.replace(replacement);
}
@NotNull
@Override
public PsiDocTag createParamTag(@NotNull final String parameterName, @NonNls final String description) throws IncorrectOperationException {
@NonNls final StringBuilder builder = new StringBuilder();
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());
}
@NotNull
@Override
public PsiAnnotation createAnnotationFromText(@NotNull final String annotationText, @Nullable final PsiElement context) throws IncorrectOperationException {
final PsiAnnotation psiAnnotation = super.createAnnotationFromText(annotationText, context);
GeneratedMarkerVisitor.markGenerated(psiAnnotation);
return psiAnnotation;
}
@NotNull
@Override
public PsiCodeBlock createCodeBlockFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
final PsiCodeBlock psiCodeBlock = super.createCodeBlockFromText(text, context);
GeneratedMarkerVisitor.markGenerated(psiCodeBlock);
return psiCodeBlock;
}
@NotNull
@Override
public PsiEnumConstant createEnumConstantFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
final PsiEnumConstant enumConstant = super.createEnumConstantFromText(text, context);
GeneratedMarkerVisitor.markGenerated(enumConstant);
return enumConstant;
}
@NotNull
@Override
public PsiExpression createExpressionFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
final PsiExpression expression = super.createExpressionFromText(text, context);
GeneratedMarkerVisitor.markGenerated(expression);
return expression;
}
@NotNull
@Override
public PsiField createFieldFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
final PsiField psiField = super.createFieldFromText(text, context);
GeneratedMarkerVisitor.markGenerated(psiField);
return psiField;
}
@NotNull
@Override
public PsiParameter createParameterFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
final PsiParameter parameter = super.createParameterFromText(text, context);
GeneratedMarkerVisitor.markGenerated(parameter);
return parameter;
}
@NotNull
@Override
public PsiStatement createStatementFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
final PsiStatement statement = super.createStatementFromText(text, context);
GeneratedMarkerVisitor.markGenerated(statement);
return statement;
}
@NotNull
@Override
public PsiType createTypeFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
return createTypeInner(text, context, true);
}
@NotNull
@Override
public PsiTypeParameter createTypeParameterFromText(@NotNull final String text,
final PsiElement context) throws IncorrectOperationException {
final PsiTypeParameter typeParameter = super.createTypeParameterFromText(text, context);
GeneratedMarkerVisitor.markGenerated(typeParameter);
return typeParameter;
}
@NotNull
@Override
public PsiMethod createMethodFromText(@NotNull final String text,
final PsiElement context,
final LanguageLevel level) throws IncorrectOperationException {
final PsiMethod method = super.createMethodFromText(text, context, level);
GeneratedMarkerVisitor.markGenerated(method);
return method;
}
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 final JavaParserUtil.ParserWrapper CATCH_SECTION = new JavaParserUtil.ParserWrapper() {
@Override
public void parse(final PsiBuilder builder) {
JavaParser.INSTANCE.getStatementParser().parseCatchBlock(builder);
}
};
@NotNull
@Override
public PsiCatchSection createCatchSection(@NotNull final PsiType exceptionType,
@NotNull final String exceptionName,
@Nullable final PsiElement context) throws IncorrectOperationException {
if (!(exceptionType instanceof PsiClassType || exceptionType instanceof PsiDisjunctionType)) {
throw new IncorrectOperationException("Unexpected type:" + exceptionType);
}
@NonNls final String text = "catch (" + exceptionType.getCanonicalText(true) + " " + exceptionName + ") {}";
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, CATCH_SECTION, level(context)), context);
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
if (!(element instanceof PsiCatchSection)) {
throw new IncorrectOperationException("Incorrect catch section '" + text + "'. Parsed element: " + element);
}
final Project project = myManager.getProject();
final JavaPsiImplementationHelper helper = JavaPsiImplementationHelper.getInstance(project);
helper.setupCatchBlock(exceptionName, exceptionType, context, (PsiCatchSection)element);
final CodeStyleManager styleManager = CodeStyleManager.getInstance(project);
final PsiCatchSection catchSection = (PsiCatchSection)styleManager.reformat(element);
GeneratedMarkerVisitor.markGenerated(catchSection);
return catchSection;
}
@Override
public boolean isValidClassName(@NotNull String name) {
return isIdentifier(name);
}
@Override
public boolean isValidMethodName(@NotNull String name) {
return isIdentifier(name);
}
@Override
public boolean isValidParameterName(@NotNull String name) {
return isIdentifier(name);
}
@Override
public boolean isValidFieldName(@NotNull String name) {
return isIdentifier(name);
}
@Override
public boolean isValidLocalVariableName(@NotNull String name) {
return isIdentifier(name);
}
private boolean isIdentifier(@NotNull String name) {
return PsiNameHelper.getInstance(myManager.getProject()).isIdentifier(name);
}
}