/* * Copyright 2013 Guidewire Software, Inc. */ package gw.plugin.ij.lang.psi.impl; import com.intellij.lang.ASTNode; import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import gw.internal.gosu.parser.AbstractTypeRef; import gw.lang.parser.IGosuParser; import gw.lang.parser.IGosuValidator; import gw.lang.parser.ISymbolTable; import gw.lang.parser.ITypeUsesMap; import gw.lang.parser.ParserOptions; import gw.lang.parser.exceptions.ParseResultsException; import gw.lang.parser.exceptions.SymbolNotFoundException; import gw.lang.parser.statements.IClassFileStatement; import gw.lang.parser.statements.IClassStatement; import gw.lang.reflect.IType; import gw.lang.reflect.TypeSystem; import gw.lang.reflect.gs.IGosuProgram; import gw.lang.reflect.module.Dependency; import gw.lang.reflect.module.IModule; import gw.plugin.ij.icons.GosuIcons; import gw.plugin.ij.lang.GosuLanguage; import gw.plugin.ij.lang.parser.GosuAstTransformer; import gw.plugin.ij.lang.psi.util.GosuPsiParseUtil; import gw.plugin.ij.util.FileUtil; import gw.plugin.ij.util.InjectedElementEditor; import org.jetbrains.annotations.NotNull; import javax.swing.*; public class GosuProgramFileImpl extends AbstractGosuClassFileImpl { public GosuProgramFileImpl(@NotNull FileViewProvider viewProvider) { super(viewProvider, GosuLanguage.instance()); } @SuppressWarnings({"CloneDoesntDeclareCloneNotSupportedException"}) protected GosuProgramFileImpl clone() { return (GosuProgramFileImpl) super.clone(); } public ASTNode parse(@NotNull ASTNode chameleon) { return GosuAstTransformer.instance().transformProgram(chameleon, (IGosuProgram) parseType(false)).getFirstChildNode(); } @Override protected IGosuParser createParser(CharSequence contents) { final IGosuParser parser = super.createParser(contents); final ITypeUsesMap typeUsesMap = GosuParserConfigurer.getTypeUsesMap(this); if (typeUsesMap != null && parser.getTypeUsesMap() != typeUsesMap) { parser.setTypeUsesMap(typeUsesMap); } final ISymbolTable symbolTable = GosuParserConfigurer.getSymbolTable(this); if (symbolTable != null) { parser.setSymbolTable(symbolTable); } final IGosuValidator validator = GosuParserConfigurer.getValidator(this); if (validator != null) { parser.setValidator(validator); } return parser; } protected ParserOptions createParserOptions() { return new ParserOptions(); } public IGosuProgram parseType(String strClassName, String contents, int completionMarkerOffset) { final IModule module = getModule(); TypeSystem.pushModule(module); // DP: this line should execute outside the TS lock to avoid deadlock final IGosuParser parser = createParser(contents); TypeSystem.lock(); try { //refreshTheOldType(strClassName, module); IGosuProgram program; IClassFileStatement classFileStmt; ISymbolTable snapshotSymbols = null; IType ctxType = null; try { if (completionMarkerOffset >= 0) { parser.setSnapshotSymbols(); } program = GosuPsiParseUtil.parseProgram(parser, createParserOptions(), new ModuleFileContext(module, strClassName), contents); classFileStmt = program.getClassStatement().getClassFileStatement(); } catch (ParseResultsException ex) { classFileStmt = (IClassFileStatement) ex.getParsedElement(); IClassStatement classStatement = classFileStmt.getClassStatement(); program = classStatement != null ? (IGosuProgram) classStatement.getGosuClass() : null; final SymbolNotFoundException issue = getExceptionWithSymbolTable(ex); if (issue != null) { snapshotSymbols = issue.getSymbolTable(); ctxType = issue.getExpectedType(); } } if (getOriginalFile().getVirtualFile() != null) { final GosuClassParseData data = getParseData(); data.setClassFileStatement(classFileStmt); data.setSource(contents); if (completionMarkerOffset >= 0) { data.setSnapshotSymbols(snapshotSymbols); data.setContextType(ctxType); } } if (strClassName.contains(FileUtil.MAGIC_INJECTED_SUFFIX)) { ((AbstractTypeRef) program).setReloadable(false); } return program; } finally { TypeSystem.unlock(); TypeSystem.popModule(module); } } protected void addDependencies(@NotNull IModule gsModule) { final IModule jre = gsModule.getExecutionEnvironment().getJreModule(); gsModule.addDependency(new Dependency(jre, true)); } @Override public void setPackageName(String packageName) throws IncorrectOperationException { // do nothing, no package stmt in program // TODO: thorw exception here? } @Override public PsiElement getNavigationElement() { return InjectedElementEditor.getOriginalFile(this); } @Override protected Icon getElementIcon(@IconFlags int flags) { return GosuIcons.FILE_PROGRAM; } }