Package com.redhat.ceylon.compiler.java.loader

Source Code of com.redhat.ceylon.compiler.java.loader.CeylonEnter$JavacAssertionVisitor

/*
* Copyright Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the authors tag. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License version 2.
*
* This particular file is subject to the "Classpath" exception as provided in the
* LICENSE file that accompanied this code.
*
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE.  See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License,
* along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA  02110-1301, USA.
*/

package com.redhat.ceylon.compiler.java.loader;

import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashSet;
import java.util.Set;

import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject.Kind;
import javax.tools.StandardLocation;

import com.redhat.ceylon.cmr.api.ArtifactContext;
import com.redhat.ceylon.cmr.api.ArtifactResult;
import com.redhat.ceylon.cmr.api.RepositoryManager;
import com.redhat.ceylon.cmr.impl.InvalidArchiveException;
import com.redhat.ceylon.compiler.java.codegen.AnnotationModelVisitor;
import com.redhat.ceylon.compiler.java.codegen.BoxingDeclarationVisitor;
import com.redhat.ceylon.compiler.java.codegen.BoxingVisitor;
import com.redhat.ceylon.compiler.java.codegen.CeylonCompilationUnit;
import com.redhat.ceylon.compiler.java.codegen.CeylonTransformer;
import com.redhat.ceylon.compiler.java.codegen.CodeGenError;
import com.redhat.ceylon.compiler.java.codegen.CompilerBoxingDeclarationVisitor;
import com.redhat.ceylon.compiler.java.codegen.CompilerBoxingVisitor;
import com.redhat.ceylon.compiler.java.codegen.DeferredVisitor;
import com.redhat.ceylon.compiler.java.codegen.DefiniteAssignmentVisitor;
import com.redhat.ceylon.compiler.java.codegen.MissingNativeVisitor;
import com.redhat.ceylon.compiler.java.codegen.UnsupportedVisitor;
import com.redhat.ceylon.compiler.java.codegen.InterfaceVisitor;
import com.redhat.ceylon.compiler.java.codegen.TypeParameterCaptureVisitor;
import com.redhat.ceylon.compiler.java.tools.CeylonLog;
import com.redhat.ceylon.compiler.java.tools.CeylonPhasedUnit;
import com.redhat.ceylon.compiler.java.tools.CeyloncFileManager;
import com.redhat.ceylon.compiler.java.tools.LanguageCompiler;
import com.redhat.ceylon.compiler.java.tools.LanguageCompiler.CompilerDelegate;
import com.redhat.ceylon.compiler.java.util.Timer;
import com.redhat.ceylon.compiler.java.util.Util;
import com.redhat.ceylon.compiler.loader.AbstractModelLoader;
import com.redhat.ceylon.compiler.loader.model.LazyModule;
import com.redhat.ceylon.compiler.typechecker.analyzer.AnalysisError;
import com.redhat.ceylon.compiler.typechecker.analyzer.UnsupportedError;
import com.redhat.ceylon.compiler.typechecker.analyzer.UsageWarning;
import com.redhat.ceylon.compiler.typechecker.context.PhasedUnit;
import com.redhat.ceylon.compiler.typechecker.context.PhasedUnits;
import com.redhat.ceylon.compiler.typechecker.model.Declaration;
import com.redhat.ceylon.compiler.typechecker.model.Module;
import com.redhat.ceylon.compiler.typechecker.model.ProducedType;
import com.redhat.ceylon.compiler.typechecker.model.Setter;
import com.redhat.ceylon.compiler.typechecker.model.TypedDeclaration;
import com.redhat.ceylon.compiler.typechecker.model.Unit;
import com.redhat.ceylon.compiler.typechecker.parser.ParseError;
import com.redhat.ceylon.compiler.typechecker.parser.LexError;
import com.redhat.ceylon.compiler.typechecker.tree.Node;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.CompilationUnit;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.CompilerAnnotation;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.Statement;
import com.redhat.ceylon.compiler.typechecker.tree.UnexpectedError;
import com.redhat.ceylon.compiler.typechecker.util.AssertionVisitor;
import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Type.ClassType;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Check;
import com.sun.tools.javac.comp.Enter;
import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.comp.Todo;
import com.sun.tools.javac.file.Paths;
import com.sun.tools.javac.main.OptionName;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.util.Abort;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Options;
import com.sun.tools.javac.util.SourceLanguage;
import com.sun.tools.javac.util.SourceLanguage.Language;

public class CeylonEnter extends Enter {

    public static CeylonEnter instance(Context context) {
        CeylonEnter instance = (CeylonEnter)context.get(enterKey);
        if (instance == null){
            instance = new CeylonEnter(context);
            context.put(enterKey, instance);
        }
        return instance;
    }

    private CeylonTransformer gen;
    private boolean hasRun = false;
    private PhasedUnits phasedUnits;
    private CompilerDelegate compilerDelegate;
    private Log log;
    private AbstractModelLoader modelLoader;
    private Options options;
    private Timer timer;
    private Paths paths;
    private CeyloncFileManager fileManager;
    private boolean verbose;
    private Check chk;
    private Types types;
    private Symtab symtab;
    private Todo todo;
    private boolean isBootstrap;
    private Annotate annotate;
    private Set<Module> modulesAddedToClassPath = new HashSet<Module>();
    private TaskListener taskListener;
    private SourceLanguage sourceLanguage;

   
    protected CeylonEnter(Context context) {
        super(context);
        // make sure it's loaded first
        CeylonClassReader.instance(context);
        try {
            gen = CeylonTransformer.getInstance(context);
        } catch (Exception e) {
            // FIXME
            e.printStackTrace();
        }
        phasedUnits = LanguageCompiler.getPhasedUnitsInstance(context);
        compilerDelegate = LanguageCompiler.getCompilerDelegate(context);
        log = CeylonLog.instance(context);
        modelLoader = CeylonModelLoader.instance(context);
        options = Options.instance(context);
        timer = Timer.instance(context);
        paths = Paths.instance(context);
        fileManager = (CeyloncFileManager) context.get(JavaFileManager.class);
        verbose = options.get(OptionName.VERBOSE) != null;
        isBootstrap = options.get(OptionName.BOOTSTRAPCEYLON) != null;
        chk = Check.instance(context);
        types = Types.instance(context);
        symtab = Symtab.instance(context);
        todo = Todo.instance(context);
        annotate = Annotate.instance(context);
        taskListener = context.get(TaskListener.class);
        sourceLanguage = SourceLanguage.instance(context);

        // now superclass init
        init(context);
    }

    @Override
    public void main(List<JCCompilationUnit> trees) {
        // complete the javac AST with a completed ceylon model
        timer.startTask("prepareForTypeChecking");
        prepareForTypeChecking(trees);
        timer.endTask();
        List<JCCompilationUnit> javaTrees = List.nil();
        List<JCCompilationUnit> ceylonTrees = List.nil();
        // split them in two sets: java and ceylon
        for(JCCompilationUnit tree : trees){
            if(tree instanceof CeylonCompilationUnit)
                ceylonTrees = ceylonTrees.prepend(tree);
            else
                javaTrees = javaTrees.prepend(tree);
        }
        timer.startTask("Enter on Java trees");
        // enter java trees first to set up their ClassSymbol objects for ceylon trees to use during type-checking
        if(isBootstrap){
            super.main(trees);
        }else if(!javaTrees.isEmpty()){
            super.main(javaTrees);
        }
        // now we can type-check the Ceylon code
        completeCeylonTrees(trees);
        if(isBootstrap){
            // bootstrapping the language module is a bit more complex
            resetAndRunEnterAgain(trees);
        }else{
            timer.startTask("Enter on Ceylon trees");
            // and complete their new trees
            try {
                sourceLanguage.push(Language.CEYLON);
                super.main(ceylonTrees);                   
            } finally {
                sourceLanguage.pop();
            }
            timer.endTask();
        }
    }

    private void resetAndRunEnterAgain(List<JCCompilationUnit> trees) {
        timer.startTask("Resetting all trees for bootstrap");
       
        // get rid of some caches and state
        chk.compiled.clear();
        types.reset();
        annotate.reset();
        super.reset();
       
        // reset all class symbols
        for(ClassSymbol classSymbol : symtab.classes.values()){
            if(Util.isLoadedFromSource(classSymbol)
                    || (classSymbol.sourcefile != null && classSymbol.sourcefile.getKind() == Kind.SOURCE)){
                PackageSymbol pkg = classSymbol.packge();
                String name = pkg.getQualifiedName().toString();
                if(name.startsWith(AbstractModelLoader.CEYLON_LANGUAGE) || name.startsWith("com.redhat.ceylon.compiler.java"))
                    resetClassSymbol(classSymbol);
            }
        }
       
        // reset the trees
        JCTypeResetter jcTypeResetter = new JCTypeResetter();
        for(JCCompilationUnit tree : trees){
            tree.accept(jcTypeResetter);
        }
       
        // and reset the list of things to compile, because we got rid of the Env key we used to look them up
        // so they'd appear as extra things to compile when we do Enter
        todo.reset();
        timer.endTask();
       
        timer.startTask("Enter on Java+Ceylon trees");
        // now do Enter on all the java+ceylon code
        super.main(trees);
        timer.endTask();
    }

    /**
     * This resets a ClassSymbol recursively, for bootstrap
     */
    private void resetClassSymbol(ClassSymbol classSymbol) {
        // look for inner classes
        if(classSymbol.members_field != null){
            for(Symbol member : classSymbol.getEnclosedElements()){
                if(member instanceof ClassSymbol){
                    resetClassSymbol((ClassSymbol)member);
                }
            }
        }
       
        // reset its type, we need to keep it
        Type.ClassType classType = (ClassType) classSymbol.type;
        classType.all_interfaces_field = null;
        classType.interfaces_field = null;
        classType.supertype_field = null;
        classType.typarams_field = null;
       
        // reset its members and completer
        classSymbol.members_field = null;
        classSymbol.completer = null;
    }

    @Override
    protected Type classEnter(JCTree tree, Env<AttrContext> env) {
        if(tree instanceof CeylonCompilationUnit){
            sourceLanguage.push(Language.CEYLON);
            try{
                return super.classEnter(tree, env);
            }finally{
                sourceLanguage.pop();
            }
        }else
            return super.classEnter(tree, env);
    }
   
    public void prepareForTypeChecking(List<JCCompilationUnit> trees) {
        if (hasRun)
            throw new RuntimeException("Waaaaa, running twice!!!");
        //By now le language module version should be known (as local)
        //or we should use the default one.
        int numParserErrors = log.nerrors;
        // load the standard modules
        timer.startTask("loadStandardModules");
        compilerDelegate.loadStandardModules(modelLoader);
        timer.endTask();

        // load the modules we are compiling first
        hasRun = true;
       
        // make sure we don't load the files we are compiling from their class files
        timer.startTask("setupSourceFileObjects");
        compilerDelegate.setupSourceFileObjects(trees, modelLoader);
        timer.endTask();
      
        // resolve module dependencies
        timer.startTask("verifyModuleDependencyTree");
        compilerDelegate.resolveModuleDependencies(phasedUnits);
        timer.endTask();
       
        // now load package descriptors
        timer.startTask("loadPackageDescriptors");
        compilerDelegate.loadPackageDescriptors(modelLoader);
        timer.endTask();
       
        // at this point, abort if we had any errors logged due to module descriptors
        timer.startTask("collectTreeErrors");
        collectTreeErrors(false, false);
        timer.endTask();
        // check if we abort on errors or not
        if (options.get(OptionName.CEYLONCONTINUE) == null) {
            // if we didn't have any errors on module descriptors,
            // we can go on, none were logged so
            // they can't be re-logged and duplicated later on
            if(log.nerrors - numParserErrors > 0)
                throw new Abort();
        }
    }

   
    public void completeCeylonTrees(List<JCCompilationUnit> trees){
        // run the type checker
        timer.startTask("Ceylon type checking");
        typeCheck();
        // some debugging
        //printModules();
        timer.startTask("Ceylon code generation");
        /*
         * Here we convert the ceylon tree to its javac AST, after the typechecker has run
         */
        Timer nested = timer.nestedTimer();
        for (JCCompilationUnit tree : trees) {
            if (tree instanceof CeylonCompilationUnit) {
                CeylonCompilationUnit ceylonTree = (CeylonCompilationUnit) tree;
                gen.setMap(ceylonTree.lineMap);
                CeylonPhasedUnit phasedUnit = (CeylonPhasedUnit)ceylonTree.phasedUnit;
                gen.setFileObject(phasedUnit.getFileObject());
                nested.startTask("Ceylon code generation for " + phasedUnit.getUnitFile().getName());
                TaskEvent event = new TaskEvent(TaskEvent.Kind.PARSE, tree);
                if (taskListener != null) {
                    taskListener.started(event);
                }
                ceylonTree.defs = gen.transformAfterTypeChecking(ceylonTree.ceylonTree).toList();
                if (taskListener != null) {
                    taskListener.finished(event);
                }
                nested.endTask();
                if(isVerbose("ast")){
                    System.err.println("Model tree for "+tree.getSourceFile());
                    System.err.println(ceylonTree.ceylonTree);
                }
                if(isVerbose("code")){
                    System.err.println("Java code generated for "+tree.getSourceFile());
                    System.err.println(ceylonTree);
                }
            }
        }
        timer.startTask("Ceylon error generation");
        printGeneratorErrors();
        timer.endTask();
        // write some stats
        if(verbose)
            modelLoader.printStats();
    }

    private boolean isVerbose(String key) {
        return verbose || options.get(OptionName.VERBOSE + ":" + key) != null;
    }

    public void addOutputModuleToClassPath(Module module){
        RepositoryManager repositoryManager = fileManager.getOutputRepositoryManager();
        ArtifactResult artifact = null;
        try {
            ArtifactContext ctx = new ArtifactContext(module.getNameAsString(), module.getVersion(), ArtifactContext.CAR, ArtifactContext.JAR);
            artifact = repositoryManager.getArtifactResult(ctx);
        } catch (InvalidArchiveException e) {
            log.error("ceylon", "Module car " + e.getPath()
                    +" obtained from repository " + e.getRepository()
                    +" has an invalid SHA1 signature: you need to remove it and rebuild the archive, since it"
                    +" may be corrupted.");
        } catch (Exception e) {
            String moduleName = module.getNameAsString();
            if(!module.isDefault())
                moduleName += "/" + module.getVersion();
            log.error("ceylon", "Exception occured while trying to resolve module "+moduleName);
            e.printStackTrace();
        }
        addModuleToClassPath(module, false, artifact);
    }
   
    public boolean isModuleInClassPath(Module module){
        return modulesAddedToClassPath.contains(module);
    }
   
    public void addModuleToClassPath(Module module, boolean errorIfMissing, ArtifactResult result) {
        if(verbose)
            Log.printLines(log.noticeWriter, "[Adding module to classpath: "+module.getNameAsString()+"/"+module.getVersion()+"]");       
       
        Paths.Path classPath = paths.getPathForLocation(StandardLocation.CLASS_PATH);

        File artifact = null;
        try {
            artifact = result != null ? result.artifact() : null;
        } catch (Exception e) {
            String moduleName = module.getNameAsString();
            if(!module.isDefault())
                moduleName += "/" + module.getVersion();
            log.error("ceylon", "Exception occured while trying to resolve module "+moduleName);
            e.printStackTrace();
        }
       
        if(verbose){
            if(artifact != null)
                Log.printLines(log.noticeWriter, "[Found module at : "+artifact.getPath()+"]");
            else
                Log.printLines(log.noticeWriter, "[Could not find module]");
        }

        if(modulesAddedToClassPath.add(module)){
            if(artifact != null && artifact.exists()){
                classPath.add(artifact);
                ((LazyModule)module).loadPackageList(result);
            }else if(errorIfMissing){
                log.error("ceylon", "Failed to find module "+module.getNameAsString()+"/"+module.getVersion()+" in repositories");
            }
        }else if(verbose){
            Log.printLines(log.noticeWriter, "[Module already added to classpath]");
        }
    }

    private void typeCheck() {
        final java.util.List<PhasedUnit> listOfUnits = phasedUnits.getPhasedUnits();

        // Delegate to an external typechecker (e.g. the IDE build)
        compilerDelegate.typeCheck(listOfUnits);

        // This phase is proper to the Java backend
        for (PhasedUnit pu : listOfUnits) {
            Unit unit = pu.getUnit();
            final CompilationUnit compilationUnit = pu.getCompilationUnit();
            for (Declaration d: unit.getDeclarations()) {
                if (d instanceof TypedDeclaration && !(d instanceof Setter)) {
                    compilationUnit.visit(new MethodOrValueReferenceVisitor((TypedDeclaration) d));
                }
            }
        }
       
        UnsupportedVisitor uv = new UnsupportedVisitor();
        MissingNativeVisitor mnv = new MissingNativeVisitor(modelLoader);
        BoxingDeclarationVisitor boxingDeclarationVisitor = new CompilerBoxingDeclarationVisitor(gen);
        BoxingVisitor boxingVisitor = new CompilerBoxingVisitor(gen);
        DeferredVisitor deferredVisitor = new DeferredVisitor();
        AnnotationModelVisitor amv = new AnnotationModelVisitor(gen);
        DefiniteAssignmentVisitor dav = new DefiniteAssignmentVisitor();
        TypeParameterCaptureVisitor tpCaptureVisitor = new TypeParameterCaptureVisitor();
        InterfaceVisitor localInterfaceVisitor = new InterfaceVisitor();
        // Extra phases for the compiler
       
        // boxing visitor depends on boxing decl
        for (PhasedUnit pu : listOfUnits) {
            pu.getCompilationUnit().visit(uv);
        }
        for (PhasedUnit pu : listOfUnits) {
            pu.getCompilationUnit().visit(boxingDeclarationVisitor);
        }
        // the others can run at the same time
        for (PhasedUnit pu : listOfUnits) {
            CompilationUnit compilationUnit = pu.getCompilationUnit();
            compilationUnit.visit(mnv);
            compilationUnit.visit(boxingVisitor);
            compilationUnit.visit(deferredVisitor);
            compilationUnit.visit(amv);
            compilationUnit.visit(dav);
            compilationUnit.visit(tpCaptureVisitor);
            compilationUnit.visit(localInterfaceVisitor);
        }
       
        collectTreeErrors(true, true);
    }

    private void collectTreeErrors(boolean runAssertions, final boolean reportWarnings) {
        final java.util.List<PhasedUnit> listOfUnits = phasedUnits.getPhasedUnits();

        for (PhasedUnit pu : listOfUnits) {
            pu.getCompilationUnit().visit(new JavacAssertionVisitor((CeylonPhasedUnit) pu, runAssertions){
                @Override
                protected void out(UnexpectedError err) {
                    setSource();
                    logError(getPosition(err.getTreeNode()), "ceylon", err.getMessage());
                }
                @Override
                protected void out(AnalysisError err) {
                    setSource();
                    Node node = getIdentifyingNode(err.getTreeNode());
                    logError(getPosition(node), "ceylon", err.getMessage());
                }
                @Override
                protected void out(Node that, LexError err) {
                    setSource();
                    int pos = getPosition((err.getLine()), err.getCharacterInLine());
                    logError(pos, "ceylon", err.getMessage());
                }
                @Override
                protected void out(Node that, ParseError err) {
                    setSource();
                    int pos = getPosition((err.getLine()), err.getCharacterInLine());
                    logError(pos, "ceylon", err.getMessage());
                }
                @Override
                protected void out(UnsupportedError err) {
                    setSource();
                    Node node = getIdentifyingNode(err.getTreeNode());
                    logError(getPosition(node), "ceylon", err.getMessage());
                }
                @Override
                protected void out(UsageWarning warning) {
                    if (reportWarnings && !warning.isSuppressed()) {
                        setSource();
                        Node node = getIdentifyingNode(warning.getTreeNode());
                        logWarning(getPosition(node), "ceylon", warning.getMessage());
                    }
                }
                @Override
                protected void out(Node that, String message) {
                    setSource();
                    logError(getPosition(that), "ceylon", message);
                }
            });
        }
    }

    /**
     * Visits the nodes of each unit calling
     * {@link #logError(int, String, String)} for each {@link CodeGenError}
     */
    private void printGeneratorErrors() {
        final java.util.List<PhasedUnit> listOfUnits = phasedUnits.getPhasedUnits();

        for (PhasedUnit pu : listOfUnits) {
            pu.getCompilationUnit().visit(new JavacAssertionVisitor((CeylonPhasedUnit) pu, false){
                @Override
                protected void out(UnexpectedError err) {
                    if(err instanceof CodeGenError){
                        CodeGenError error = ((CodeGenError)err);
                        String location = locationInfo(error);
                        logError(getPosition(err.getTreeNode()),
                                "ceylon.codegen.exception",
                                "compiler bug: "+error.getMessage()+" at " + location);
                    }
                }
                private String locationInfo(CodeGenError error) {
                    if (error.getCause() != null
                            && error.getCause().getStackTrace() != null
                            && error.getCause().getStackTrace().length > 0) {
                        return error.getCause().getStackTrace()[0].toString();
                    } else {
                        return "unknown";
                    }
                }
                // Ignore those
                @Override
                protected void out(AnalysisError err) {}
                @Override
                protected void out(UnsupportedError err) {}
                @Override
                protected void out(UsageWarning warn) {}
                @Override
                protected void out(Node that, ParseError err) {}
                @Override
                protected void out(Node that, LexError err) {}
                @Override
                protected void out(Node that, String message) {}
            });
        }
    }

    protected void logError(int position, String key, String message) {
        boolean prev = log.multipleErrors;
        // we want multiple errors for Ceylon
        log.multipleErrors = true;
        try{
            log.error(position, key, message);
        }finally{
            log.multipleErrors = prev;
        }
    }

    protected void logWarning(int position, String key, String message) {
        boolean prev = log.multipleErrors;
        // we want multiple errors for Ceylon
        log.multipleErrors = true;
        try{
            log.warning(position, key, message);
        }finally{
            log.multipleErrors = prev;
        }
    }
   
    protected void logStackTrace(String key, Throwable t) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        t.printStackTrace(pw);
        pw.close();
        String tracktrace = sw.toString();
        boolean prev = log.multipleErrors;
        // we want multiple errors for Ceylon
        log.multipleErrors = true;
        try{
            log.printErrLines(key, tracktrace);
        }finally{
            log.multipleErrors = prev;
        }
    }

    private class JavacAssertionVisitor extends AssertionVisitor {
        private CeylonPhasedUnit cpu;
        protected final boolean runAssertions;
        JavacAssertionVisitor(CeylonPhasedUnit cpu, boolean runAssertions){
            this.cpu = cpu;
            this.runAssertions = runAssertions;
            this.includeUsageWarnings(true);
        }
       
        @Override
        protected void checkType(Statement that, ProducedType type, Node typedNode) {
            if(runAssertions)
                super.checkType(that, type, typedNode);
        }
       
        protected Node getIdentifyingNode(Node node) {
            return com.redhat.ceylon.compiler.typechecker.tree.Util.getIdentifyingNode(node);
        }
       
        protected int getPosition(int line, int characterInLine) {
            if (line<1) {
                return -1;
            }
            try {
                return cpu.getLineMap().getPosition(line,characterInLine);
            }
            catch (ArrayIndexOutOfBoundsException aie) {
                if (line<2) {
                    return -1;
                }
                return cpu.getLineMap().getPosition(line-1, 0);
            }
        }
       
        protected int getPosition(Node node) {
            if(node != null && node.getToken() != null)
                return getPosition(node.getToken().getLine(),
                        node.getToken().getCharPositionInLine());
            else
                return -1;
        }
       
        protected void setSource() {
            log.useSource(cpu.getFileObject());
        }
       
        @Override
        protected void initExpectingError(java.util.List<CompilerAnnotation> annotations) {
            if (runAssertions) {
                super.initExpectingError(annotations);
            }
        }
    }
   
    public boolean hasRun(){
        return hasRun;
    }
}
TOP

Related Classes of com.redhat.ceylon.compiler.java.loader.CeylonEnter$JavacAssertionVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.