blob: 1933626770dcfe265e6ebef57b6fabaa4be9508c [file] [log] [blame]
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* @author max
*/
package com.intellij.psi.impl;
import com.intellij.lang.*;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeRegistry;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.DummyHolder;
import com.intellij.psi.impl.source.DummyHolderFactory;
import com.intellij.psi.impl.source.PsiPlainTextFileImpl;
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.tree.IElementType;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.util.LocalTimeCounter;
import com.intellij.util.text.CharSequenceSubSequence;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class PsiFileFactoryImpl extends PsiFileFactory {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiFileFactoryImpl");
private final PsiManager myManager;
public PsiFileFactoryImpl(final PsiManager manager) {
myManager = manager;
}
@Override
@NotNull
public PsiFile createFileFromText(@NotNull String name, @NotNull FileType fileType, @NotNull CharSequence text,
long modificationStamp, final boolean eventSystemEnabled) {
return createFileFromText(name, fileType, text, modificationStamp, eventSystemEnabled, true);
}
@Override
public PsiFile createFileFromText(@NotNull String name, @NotNull Language language, @NotNull CharSequence text) {
return createFileFromText(name, language, text, true, true);
}
@Override
public PsiFile createFileFromText(@NotNull String name, @NotNull Language language, @NotNull CharSequence text, boolean eventSystemEnabled, boolean markAsCopy) {
return createFileFromText(name, language, text, eventSystemEnabled, markAsCopy, false);
}
@Override
public PsiFile createFileFromText(@NotNull String name,
@NotNull Language language,
@NotNull CharSequence text,
boolean eventSystemEnabled,
boolean markAsCopy,
boolean noSizeLimit) {
LightVirtualFile virtualFile = new LightVirtualFile(name, language, text);
if (noSizeLimit) {
SingleRootFileViewProvider.doNotCheckFileSizeLimit(virtualFile);
}
return trySetupPsiForFile(virtualFile, language, eventSystemEnabled, markAsCopy);
}
@Override
@NotNull
public PsiFile createFileFromText(@NotNull String name,
@NotNull FileType fileType,
@NotNull CharSequence text,
long modificationStamp,
final boolean eventSystemEnabled,
boolean markAsCopy) {
final LightVirtualFile virtualFile = new LightVirtualFile(name, fileType, text, modificationStamp);
if(fileType instanceof LanguageFileType){
final Language language =
LanguageSubstitutors.INSTANCE.substituteLanguage(((LanguageFileType)fileType).getLanguage(), virtualFile, myManager.getProject());
final PsiFile file = trySetupPsiForFile(virtualFile, language, eventSystemEnabled, markAsCopy);
if (file != null) return file;
}
final SingleRootFileViewProvider singleRootFileViewProvider =
new SingleRootFileViewProvider(myManager, virtualFile, eventSystemEnabled);
final PsiPlainTextFileImpl plainTextFile = new PsiPlainTextFileImpl(singleRootFileViewProvider);
if(markAsCopy) CodeEditUtil.setNodeGenerated(plainTextFile.getNode(), true);
return plainTextFile;
}
@Nullable
public PsiFile trySetupPsiForFile(final LightVirtualFile virtualFile, Language language,
final boolean physical, final boolean markAsCopy) {
final FileViewProviderFactory factory = LanguageFileViewProviders.INSTANCE.forLanguage(language);
FileViewProvider viewProvider = factory != null ? factory.createFileViewProvider(virtualFile, language, myManager, physical) : null;
if (viewProvider == null) viewProvider = new SingleRootFileViewProvider(myManager, virtualFile, physical);
language = viewProvider.getBaseLanguage();
final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(language);
if (parserDefinition != null) {
final PsiFile psiFile = viewProvider.getPsi(language);
if (psiFile != null) {
if (markAsCopy) {
if (psiFile.getNode() == null) {
throw new AssertionError("No node for file " + psiFile + "; language=" + language);
}
markGenerated(psiFile);
}
return psiFile;
}
}
return null;
}
@NotNull
public PsiFile createFileFromText(@NotNull String name,
@NotNull FileType fileType, final Language language, @NotNull Language targetLanguage, @NotNull CharSequence text,
long modificationStamp,
final boolean physical,
boolean markAsCopy) {
final LightVirtualFile virtualFile = new LightVirtualFile(name, fileType, text, modificationStamp);
final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(language);
final FileViewProviderFactory factory = LanguageFileViewProviders.INSTANCE.forLanguage(language);
FileViewProvider viewProvider = factory != null ? factory.createFileViewProvider(virtualFile, language, myManager, physical) : null;
if (viewProvider == null) viewProvider = new SingleRootFileViewProvider(myManager, virtualFile, physical);
if (parserDefinition != null){
final PsiFile psiFile = viewProvider.getPsi(targetLanguage);
if (psiFile != null) {
if(markAsCopy) {
markGenerated(psiFile);
}
return psiFile;
}
}
final SingleRootFileViewProvider singleRootFileViewProvider =
new SingleRootFileViewProvider(myManager, virtualFile, physical);
final PsiPlainTextFileImpl plainTextFile = new PsiPlainTextFileImpl(singleRootFileViewProvider);
if(markAsCopy) CodeEditUtil.setNodeGenerated(plainTextFile.getNode(), true);
return plainTextFile;
}
@Override
@NotNull
public PsiFile createFileFromText(@NotNull String name, @NotNull FileType fileType, @NotNull CharSequence text) {
return createFileFromText(name, fileType, text, LocalTimeCounter.currentTime(), false);
}
@Override
@NotNull
public PsiFile createFileFromText(@NotNull String name, @NotNull String text){
FileType type = FileTypeRegistry.getInstance().getFileTypeByFileName(name);
if (type.isBinary()) {
throw new RuntimeException("Cannot create binary files from text: name " + name + ", file type " + type);
}
return createFileFromText(name, type, text);
}
@Override
public PsiFile createFileFromText(FileType fileType, final String fileName, CharSequence chars, int startOffset, int endOffset) {
LOG.assertTrue(!fileType.isBinary());
final CharSequence text = startOffset == 0 && endOffset == chars.length()?chars:new CharSequenceSubSequence(chars, startOffset, endOffset);
return createFileFromText(fileName, fileType, text);
}
@Nullable
@Override
public PsiFile createFileFromText(@NotNull CharSequence chars, @NotNull PsiFile original) {
final PsiFile file = createFileFromText(original.getName(), original.getLanguage(), chars, false, true);
if (file != null) {
file.putUserData(ORIGINAL_FILE, original);
}
return file;
}
@Nullable
public PsiElement createElementFromText(@Nullable final String text,
@NotNull final Language language,
@NotNull final IElementType type,
@Nullable final PsiElement context) {
if (text == null) return null;
final DummyHolder result = DummyHolderFactory.createHolder(myManager, language, context);
final FileElement holder = result.getTreeElement();
final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(language);
if (parserDefinition == null) {
throw new AssertionError("No parser definition for " + 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);
markGenerated(result);
return node.getPsi();
}
public static void markGenerated(PsiElement element) {
final TreeElement node = (TreeElement)element.getNode();
assert node != null;
node.acceptTree(new GeneratedMarkerVisitor());
}
}