blob: 65a91e15e0064e93c930c037b1caa62fff34e788 [file] [log] [blame]
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2009-2010 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License. When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*
* Contributor(s):
*
* Portions Copyrighted 2009-2010 Sun Microsystems, Inc.
*/
package org.netbeans.api.java.source;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.TreePath;
import com.sun.source.util.Trees;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.model.JavacTypes;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.util.Context;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.swing.text.Document;
import javax.tools.Diagnostic;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.java.lexer.JavaTokenId;
import org.netbeans.api.java.source.JavaSource.Phase;
import org.netbeans.api.lexer.TokenHierarchy;
import org.netbeans.modules.java.source.parsing.CompilationInfoImpl;
import org.netbeans.modules.java.source.parsing.HackAccessor;
import org.netbeans.modules.java.source.save.ElementOverlay;
import org.netbeans.modules.parsing.api.Snapshot;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.Exceptions;
/**
*
* @author lahvac
*/
public class CompilationInfoHack extends WorkingCopy {
private final Context context;
private final ClasspathInfo cpInfo;
private FileObject file;
private String text;
private TokenHierarchy<?> th;
private final CompilationUnitTree cut;
private PositionConverter conv;
private final org.netbeans.modules.jackpot30.resolve.api.CompilationInfo resolvedInfo;
public CompilationInfoHack(org.netbeans.modules.jackpot30.resolve.api.CompilationInfo resolvedInfo) {
//TODO: a more sane ClasspathInfo:
this((JavacTaskImpl) resolvedInfo.getJavacTask(), ClasspathInfo.create(ClassPath.EMPTY, ClassPath.EMPTY, ClassPath.EMPTY), (JCCompilationUnit) resolvedInfo.getCompilationUnit(), resolvedInfo);
}
private CompilationInfoHack(JavacTaskImpl jti, ClasspathInfo cpInfo, JCCompilationUnit cut, org.netbeans.modules.jackpot30.resolve.api.CompilationInfo resolvedInfo) {
super(HackAccessor.createCII(cpInfo), ElementOverlay.getOrCreateOverlay());
this.context = jti.getContext();
this.cpInfo = cpInfo;
try {
this.text = cut.sourcefile.getCharContent(false).toString();
this.file = FileUtil.createMemoryFileSystem().getRoot().createData("Dummy.java");//XXX
Writer w = new OutputStreamWriter(this.file.getOutputStream());
w.write(this.text);
w.close();
this.th = TokenHierarchy.create(text, JavaTokenId.language());
conv = new PositionConverter(/*SnapshotHack.create(text)*/);
} catch (IllegalArgumentException ex) {
Exceptions.printStackTrace(ex);
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
this.cut = cut;
try {
Field javacTask = CompilationInfoImpl.class.getDeclaredField("javacTask");
javacTask.setAccessible(true);
javacTask.set(this.impl, jti);
Method init = WorkingCopy.class.getDeclaredMethod("init");
init.setAccessible(true);
init.invoke(this);
} catch (InvocationTargetException ex) {
Exceptions.printStackTrace(ex);
} catch (NoSuchMethodException ex) {
Exceptions.printStackTrace(ex);
} catch (IllegalArgumentException ex) {
Exceptions.printStackTrace(ex);
} catch (IllegalAccessException ex) {
Exceptions.printStackTrace(ex);
} catch (NoSuchFieldException ex) {
Exceptions.printStackTrace(ex);
} catch (SecurityException ex) {
Exceptions.printStackTrace(ex);
}
this.resolvedInfo = resolvedInfo;
}
@Override
public TreePath getChangedTree() {
return null;
}
@Override
public ClasspathInfo getClasspathInfo() {
return cpInfo;
}
@Override
public CompilationUnitTree getCompilationUnit() {
return cut;
}
@Override
public List<Diagnostic> getDiagnostics() {
//could be enabled if necessary:
throw new UnsupportedOperationException();
}
@Override
public Document getDocument() throws IOException {
return null;
}
@Override
public synchronized ElementUtilities getElementUtilities() {
return super.getElementUtilities();
}
@Override
public Elements getElements() {
return JavacElements.instance(context);
}
@Override
public FileObject getFileObject() {
return file;
}
public CompilationInfoImpl getImpl() {
throw new UnsupportedOperationException();
}
@Override
public JavaSource getJavaSource() {
throw new UnsupportedOperationException();
}
@Override
public Phase getPhase() {
return Phase.RESOLVED;
}
@Override
public PositionConverter getPositionConverter() {
return conv;
}
@Override
public Snapshot getSnapshot() {
return org.netbeans.modules.parsing.api.Source.create(file).createSnapshot();
}
@Override
public SourceVersion getSourceVersion() {
return Source.toSourceVersion(Source.instance(context));
}
@Override
public String getText() {
return text;
}
@Override
public TokenHierarchy<?> getTokenHierarchy() {
return th;
}
@Override
public List<? extends TypeElement> getTopLevelElements() throws IllegalStateException {
final List<TypeElement> result = new ArrayList<TypeElement>();
CompilationUnitTree cu = getCompilationUnit();
if (cu == null) {
return null;
}
final Trees trees = getTrees();
assert trees != null;
List<? extends Tree> typeDecls = cu.getTypeDecls();
TreePath cuPath = new TreePath(cu);
for( Tree t : typeDecls ) {
TreePath p = new TreePath(cuPath,t);
Element e = trees.getElement(p);
if ( e != null && ( e.getKind().isClass() || e.getKind().isInterface() ) ) {
result.add((TypeElement)e);
}
}
return Collections.unmodifiableList(result);
}
@Override
public synchronized TreeUtilities getTreeUtilities() {
return super.getTreeUtilities();
}
@Override
public Trees getTrees() {
return JavacTrees.instance(context);
}
@Override
public synchronized TypeUtilities getTypeUtilities() {
return super.getTypeUtilities();
}
@Override
public Types getTypes() {
return JavacTypes.instance(context);
}
public Context getContext() {
return context;
}
}