예제 #1
0
 public LanguageCompiler(Context context) {
   super(context);
   ceylonContext = getCeylonContextInstance(context);
   vfs = ceylonContext.getVfs();
   compilerDelegate = getCompilerDelegate(context);
   phasedUnits = getPhasedUnitsInstance(context);
   try {
     gen = CeylonTransformer.getInstance(context);
   } catch (Exception e) {
     throw new RuntimeException(e);
   }
   modelLoader = CeylonModelLoader.instance(context);
   ceylonEnter = CeylonEnter.instance(context);
   options = Options.instance(context);
   isBootstrap = options.get(Option.BOOTSTRAPCEYLON) != null;
   timer = Timer.instance(context);
   sourceLanguage = SourceLanguage.instance(context);
   boolean isProgressPrinted =
       options.get(Option.CEYLONPROGRESS) != null && StatusPrinter.canPrint();
   if (isProgressPrinted) {
     sp = getStatusPrinterInstance(context);
     if (taskListener == null) {
       taskListener.add(new StatusPrinterTaskListener(sp));
     }
   }
 }
예제 #2
0
 /** Get the JavaCompiler instance for this context. */
 public static JavaCompiler instance(Context context) {
   Options options = Options.instance(context);
   options.put("-Xprefer", "source");
   // make sure it's registered
   Log log = CeylonLog.instance(context);
   CeylonEnter.instance(context);
   CeylonClassWriter.instance(context);
   JavaCompiler instance = context.get(compilerKey);
   if (instance == null) instance = new LanguageCompiler(context);
   return instance;
 }
예제 #3
0
 @Override
 public void initProcessAnnotations(Iterable<? extends Processor> processors) {
   java.util.List<String> aptModules = options.getMulti(Option.CEYLONAPT);
   if (aptModules != null) {
     CeyloncFileManager dfm = (CeyloncFileManager) fileManager;
     RepositoryManager repositoryManager = dfm.getRepositoryManager();
     final Set<ModuleSpec> visited = new HashSet<>();
     StatusPrinterAptProgressListener progressListener = null;
     if (sp != null) {
       progressListener =
           new StatusPrinterAptProgressListener(sp) {
             @Override
             protected long getNumberOfModulesResolved() {
               return visited.size();
             }
           };
       sp.clearLine();
       sp.log("Starting APT resolving");
     }
     for (String aptModule : aptModules) {
       ModuleSpec moduleSpec = ModuleSpec.parse(aptModule);
       addDependenciesToAptPath(repositoryManager, moduleSpec, visited, progressListener);
     }
     if (sp != null) {
       sp.clearLine();
       sp.log("Done APT resolving");
     }
     // we only run APT if asked explicitly with the --apt flag
     super.initProcessAnnotations(processors);
   }
   // else don't do anything, which will leave the "processAnnotations" field to false
 }
예제 #4
0
 private JavaFileObject genCodeUnlessError(Env<AttrContext> env, JCClassDecl cdef)
     throws IOException {
   CeylonFileObject sourcefile = (CeylonFileObject) env.toplevel.sourcefile;
   try {
     // do not look at the global number of errors but only those for this file
     if (super.gen.genClass(env, cdef)) {
       String packageName = cdef.sym.packge().getQualifiedName().toString();
       Package pkg = modelLoader.findPackage(packageName);
       if (pkg == null) throw new RuntimeException("Failed to find package: " + packageName);
       Module module = pkg.getModule();
       if (!module.isDefaultModule()) {
         String moduleName = module.getNameAsString();
         CeylonFileObject moduleFileObject = moduleNamesToFileObjects.get(moduleName);
         // if there's no module source file object it means the module descriptor had parse errors
         if (moduleFileObject == null || moduleFileObject.hasError()) {
           // we do not produce any class files for modules with errors
           if (options.get(Option.VERBOSE) != null) {
             log.printRawLines(
                 WriterKind.NOTICE,
                 "[Not writing class "
                     + cdef.sym.className()
                     + " because its module has errors: "
                     + moduleName
                     + "]");
           }
           return null;
         }
       }
       return writer.writeClass(cdef.sym);
     }
   } catch (ClassWriter.PoolOverflow ex) {
     log.error(cdef.pos(), "limit.pool");
   } catch (ClassWriter.StringOverflow ex) {
     log.error(cdef.pos(), "limit.string.overflow", ex.value.substring(0, 20));
   } catch (CompletionFailure ex) {
     chk.completionError(cdef.pos(), ex);
   } catch (AssertionError e) {
     throw new RuntimeException("Error generating bytecode for " + sourcefile.getName(), e);
   }
   return null;
 }
예제 #5
0
 private Module loadModuleFromSource(
     String pkgName,
     LinkedList<JCCompilationUnit> moduleTrees,
     List<JCCompilationUnit> parsedTrees) {
   if (pkgName.isEmpty()) return null;
   String moduleClassName = pkgName + ".module";
   JavaFileObject fileObject;
   try {
     if (options.get(Option.VERBOSE) != null) {
       log.printRawLines(
           WriterKind.NOTICE, "[Trying to load source for module " + moduleClassName + "]");
     }
     fileObject =
         fileManager.getJavaFileForInput(
             StandardLocation.SOURCE_PATH, moduleClassName, Kind.SOURCE);
     if (options.get(Option.VERBOSE) != null) {
       log.printRawLines(WriterKind.NOTICE, "[Got file object: " + fileObject + "]");
     }
   } catch (IOException e) {
     e.printStackTrace();
     return loadModuleFromSource(getParentPackage(pkgName), moduleTrees, parsedTrees);
   }
   if (fileObject != null) {
     // first make sure we're not already compiling it: this can happen if we have several versions
     // of the
     // same module already loaded: we will get one which isn't the one we compile, but that's not
     // the one
     // we really want to compile.
     for (JCCompilationUnit parsedTree : parsedTrees) {
       if (parsedTree.sourcefile.equals(fileObject)
           && parsedTree instanceof CeylonCompilationUnit) {
         // same file! we already parsed it, let's return this one's module
         PhasedUnit phasedUnit = ((CeylonCompilationUnit) parsedTree).phasedUnit;
         // the module visitor does load the module but does not set the unit's package module
         if (phasedUnit.getPackage().getModule() == null) {
           // so find the module it created
           for (Module mod : ceylonContext.getModules().getListOfModules()) {
             // we recognise it with the unit
             if (mod.getUnit() == phasedUnit.getUnit()) {
               // set the package's module
               Package pkg = phasedUnit.getPackage();
               pkg.setModule(mod);
               mod.getPackages().add(pkg);
               modulesLoadedFromSource.add(mod);
               break;
             }
           }
         }
         // now return it
         return phasedUnit.getPackage().getModule();
       }
     }
     JCCompilationUnit javaCompilationUnit = parse(fileObject);
     Module module;
     if (javaCompilationUnit instanceof CeylonCompilationUnit) {
       CeylonCompilationUnit ceylonCompilationUnit = (CeylonCompilationUnit) javaCompilationUnit;
       moduleTrees.add(ceylonCompilationUnit);
       // parse the module info from there
       module = ceylonCompilationUnit.phasedUnit.visitSrcModulePhase();
       ceylonCompilationUnit.phasedUnit.visitRemainingModulePhase();
       // now set the module
       if (module != null) {
         ceylonCompilationUnit.phasedUnit.getPackage().setModule(module);
       }
     } else {
       // there was a syntax error in the module descriptor, make a pretend module so that we can
       // correctly mark all declarations as part of that module, but we won't generate any code
       // for it
       ModuleManager moduleManager = phasedUnits.getModuleManager();
       module = moduleManager.getOrCreateModule(Arrays.asList(pkgName.split("\\.")), "bogus");
     }
     // now remember it
     if (module != null) {
       modulesLoadedFromSource.add(module);
       return module;
     }
   }
   return loadModuleFromSource(getParentPackage(pkgName), moduleTrees, parsedTrees);
 }
예제 #6
0
  private JCCompilationUnit ceylonParse(JavaFileObject filename, CharSequence readSource) {
    if (ceylonEnter.hasRun())
      throw new RunTwiceException(
          "Trying to load new source file after CeylonEnter has been called: " + filename);
    try {
      ModuleManager moduleManager = phasedUnits.getModuleManager();
      ModuleSourceMapper moduleSourceMapper = phasedUnits.getModuleSourceMapper();
      File sourceFile = new File(filename.getName());
      // FIXME: temporary solution
      VirtualFile file = vfs.getFromFile(sourceFile);
      VirtualFile srcDir = vfs.getFromFile(getSrcDir(sourceFile));

      String source = readSource.toString();
      char[] chars = source.toCharArray();
      LineMap map = Position.makeLineMap(chars, chars.length, false);

      PhasedUnit phasedUnit = null;

      PhasedUnit externalPhasedUnit = compilerDelegate.getExternalSourcePhasedUnit(srcDir, file);

      String suppressWarnings = options.get(Option.CEYLONSUPPRESSWARNINGS);
      final EnumSet<Warning> suppressedWarnings;
      if (suppressWarnings != null) {
        if (suppressWarnings.trim().isEmpty()) {
          suppressedWarnings = EnumSet.allOf(Warning.class);
        } else {
          suppressedWarnings = EnumSet.noneOf(Warning.class);
          for (String name : suppressWarnings.trim().split(" *, *")) {
            suppressedWarnings.add(Warning.valueOf(name));
          }
        }
      } else {
        suppressedWarnings = EnumSet.noneOf(Warning.class);
      }

      if (externalPhasedUnit != null) {
        phasedUnit = new CeylonPhasedUnit(externalPhasedUnit, filename, map);
        phasedUnit.setSuppressedWarnings(suppressedWarnings);
        phasedUnits.addPhasedUnit(externalPhasedUnit.getUnitFile(), phasedUnit);
        gen.setMap(map);

        String pkgName = phasedUnit.getPackage().getQualifiedNameString();
        if ("".equals(pkgName)) {
          pkgName = null;
        }
        return gen.makeJCCompilationUnitPlaceholder(
            phasedUnit.getCompilationUnit(), filename, pkgName, phasedUnit);
      }
      if (phasedUnit == null) {
        ANTLRStringStream input = new NewlineFixingStringStream(source);
        CeylonLexer lexer = new CeylonLexer(input);

        CommonTokenStream tokens = new CommonTokenStream(lexer);

        CeylonParser parser = new CeylonParser(tokens);
        CompilationUnit cu = parser.compilationUnit();

        java.util.List<LexError> lexerErrors = lexer.getErrors();
        for (LexError le : lexerErrors) {
          printError(le, le.getMessage(), "ceylon.lexer", map);
        }

        java.util.List<ParseError> parserErrors = parser.getErrors();
        for (ParseError pe : parserErrors) {
          printError(pe, pe.getMessage(), "ceylon.parser", map);
        }

        // if we continue and it's not a descriptor, we don't care about errors
        if ((options.get(Option.CEYLONCONTINUE) != null
                && !ModuleManager.MODULE_FILE.equals(sourceFile.getName())
                && !ModuleManager.PACKAGE_FILE.equals(sourceFile.getName()))
            // otherwise we care about errors
            || (lexerErrors.size() == 0 && parserErrors.size() == 0)) {
          // FIXME: this is bad in many ways
          String pkgName = getPackage(filename);
          // make a Package with no module yet, we will resolve them later
          /*
           * Stef: see javadoc for findOrCreateModulelessPackage() for why this is here.
           */
          com.redhat.ceylon.model.typechecker.model.Package p =
              modelLoader.findOrCreateModulelessPackage(pkgName == null ? "" : pkgName);
          phasedUnit =
              new CeylonPhasedUnit(
                  file,
                  srcDir,
                  cu,
                  p,
                  moduleManager,
                  moduleSourceMapper,
                  ceylonContext,
                  filename,
                  map);
          phasedUnit.setSuppressedWarnings(suppressedWarnings);
          phasedUnits.addPhasedUnit(file, phasedUnit);
          gen.setMap(map);

          return gen.makeJCCompilationUnitPlaceholder(cu, filename, pkgName, phasedUnit);
        }
      }
    } catch (RuntimeException e) {
      throw e;
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    JCCompilationUnit result =
        make.TopLevel(List.<JCAnnotation>nil(), null, List.<JCTree>of(make.Erroneous()));
    result.sourcefile = filename;
    return result;
  }