public ReplInterpreter( @NotNull Disposable disposable, @NotNull CompilerConfiguration configuration) { KotlinCoreEnvironment environment = KotlinCoreEnvironment.createForProduction( disposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES); Project project = environment.getProject(); this.psiFileFactory = (PsiFileFactoryImpl) PsiFileFactory.getInstance(project); this.trace = new CliLightClassGenerationSupport.NoScopeRecordCliBindingTrace(); MutableModuleContext moduleContext = TopDownAnalyzerFacadeForJVM.createContextWithSealedModule(project); this.module = moduleContext.getModule(); scriptDeclarationFactory = new ScriptMutableDeclarationProviderFactory(); FileScopeProvider.AdditionalScopes scopeProvider = new FileScopeProvider.AdditionalScopes() { @NotNull @Override public List<JetScope> scopes(@NotNull JetFile file) { return lastLineScope != null ? new SmartList<JetScope>(lastLineScope) : Collections.<JetScope>emptyList(); } }; ContainerForReplWithJava container = DiPackage.createContainerForReplWithJava( moduleContext, trace, scriptDeclarationFactory, ProjectScope.getAllScope(project), scopeProvider); this.topDownAnalysisContext = new TopDownAnalysisContext( TopDownAnalysisMode.LocalDeclarations, DataFlowInfo.EMPTY, container.getResolveSession().getDeclarationScopeProvider()); this.topDownAnalyzer = container.getLazyTopDownAnalyzerForTopLevel(); this.resolveSession = container.getResolveSession(); moduleContext.initializeModuleContents( new CompositePackageFragmentProvider( Arrays.asList( container.getResolveSession().getPackageFragmentProvider(), container.getJavaDescriptorResolver().getPackageFragmentProvider()))); List<URL> classpath = Lists.newArrayList(); for (File file : getJvmClasspathRoots(configuration)) { try { classpath.add(file.toURI().toURL()); } catch (MalformedURLException e) { throw UtilsPackage.rethrow(e); } } this.classLoader = new ReplClassLoader(new URLClassLoader(classpath.toArray(new URL[classpath.size()]), null)); }
static { Map<Visibility, Integer> visibilities = UtilsPackage.newHashMapWithExpectedSize(4); visibilities.put(PRIVATE_TO_THIS, 0); visibilities.put(PRIVATE, 0); visibilities.put(INTERNAL, 1); visibilities.put(PROTECTED, 1); visibilities.put(PUBLIC, 2); ORDERED_VISIBILITIES = Collections.unmodifiableMap(visibilities); }
private void configure() { try { String path = getTestDataPath() + getTestRoot() + getTestName(true); rootDir = PsiTestUtil.createTestProjectStructure(myProject, myModule, path, myFilesToDelete, false); prepareProject(rootDir); PsiDocumentManager.getInstance(myProject).commitAllDocuments(); } catch (Exception e) { throw UtilsPackage.rethrow(e); } }
@NotNull private static String renderAccess(int access) { try { StringBuilder sb = new StringBuilder(); for (Field field : Opcodes.class.getDeclaredFields()) { String name = field.getName(); if (name.startsWith("ACC_") && (access & field.getInt(null)) != 0) { sb.append("|"); sb.append(name); } } String result = sb.toString(); return result.isEmpty() ? "<empty>" : result.substring(1); } catch (Exception e) { throw UtilsPackage.rethrow(e); } }
@NotNull private Set<JetFile> getJetBuiltInsFiles() { Set<JetFile> builtIns = getBuiltInSourceFiles(LightClassUtil.getBuiltInsDirUrl()); if (ApplicationManager.getApplication().isUnitTestMode()) { // In production, the above URL is enough as it contains sources for both native and // compilable built-ins // (it's simply the "kotlin" directory in kotlin-plugin.jar) // But in tests, sources of built-ins are not added to the classpath automatically, so we // manually specify URLs for both: // LightClassUtil.getBuiltInsDirUrl() does so for native built-ins and the code below for // compilable built-ins try { builtIns.addAll(getBuiltInSourceFiles(BUILT_INS_COMPILABLE_SRC_DIR.toURI().toURL())); } catch (MalformedURLException e) { throw UtilsPackage.rethrow(e); } } return builtIns; }
@NotNull public LineResult eval(@NotNull String line) { ++lineNumber; FqName scriptFqName = new FqName("Line" + lineNumber); Type scriptClassType = asmTypeByFqNameWithoutInnerClasses(scriptFqName); StringBuilder fullText = new StringBuilder(); for (String prevLine : previousIncompleteLines) { fullText.append(prevLine).append("\n"); } fullText.append(line); LightVirtualFile virtualFile = new LightVirtualFile( "line" + lineNumber + JetParserDefinition.STD_SCRIPT_EXT, JetLanguage.INSTANCE, fullText.toString()); virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET); JetFile psiFile = (JetFile) psiFileFactory.trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false); assert psiFile != null : "Script file not analyzed at line " + lineNumber + ": " + fullText; ReplMessageCollectorWrapper errorCollector = new ReplMessageCollectorWrapper(); AnalyzerWithCompilerReport.SyntaxErrorReport syntaxErrorReport = AnalyzerWithCompilerReport.reportSyntaxErrors( psiFile, errorCollector.getMessageCollector()); if (syntaxErrorReport.isHasErrors() && syntaxErrorReport.isAllErrorsAtEof()) { previousIncompleteLines.add(line); return LineResult.incomplete(); } previousIncompleteLines.clear(); if (syntaxErrorReport.isHasErrors()) { return LineResult.error(errorCollector.getString()); } prepareForTheNextReplLine(topDownAnalysisContext); trace.clearDiagnostics(); //noinspection ConstantConditions psiFile.getScript().putUserData(ScriptPriorities.PRIORITY_KEY, lineNumber); ScriptDescriptor scriptDescriptor = doAnalyze(psiFile, errorCollector); if (scriptDescriptor == null) { return LineResult.error(errorCollector.getString()); } List<Pair<ScriptDescriptor, Type>> earlierScripts = Lists.newArrayList(); for (EarlierLine earlierLine : earlierLines) { earlierScripts.add( Pair.create(earlierLine.getScriptDescriptor(), earlierLine.getClassType())); } GenerationState state = new GenerationState( psiFile.getProject(), ClassBuilderFactories.BINARIES, module, trace.getBindingContext(), Collections.singletonList(psiFile)); compileScript( psiFile.getScript(), scriptClassType, earlierScripts, state, CompilationErrorHandler.THROW_EXCEPTION); for (OutputFile outputFile : state.getFactory().asList()) { classLoader.addClass( JvmClassName.byInternalName(outputFile.getRelativePath().replaceFirst("\\.class$", "")), outputFile.asByteArray()); } try { Class<?> scriptClass = classLoader.loadClass(scriptFqName.asString()); Class<?>[] constructorParams = new Class<?>[earlierLines.size()]; Object[] constructorArgs = new Object[earlierLines.size()]; for (int i = 0; i < earlierLines.size(); ++i) { constructorParams[i] = earlierLines.get(i).getScriptClass(); constructorArgs[i] = earlierLines.get(i).getScriptInstance(); } Constructor<?> scriptInstanceConstructor = scriptClass.getConstructor(constructorParams); Object scriptInstance; try { scriptInstance = scriptInstanceConstructor.newInstance(constructorArgs); } catch (Throwable e) { return LineResult.error(renderStackTrace(e.getCause())); } Field rvField = scriptClass.getDeclaredField("rv"); rvField.setAccessible(true); Object rv = rvField.get(scriptInstance); earlierLines.add( new EarlierLine(line, scriptDescriptor, scriptClass, scriptInstance, scriptClassType)); JetType returnType = scriptDescriptor.getScriptCodeDescriptor().getReturnType(); return LineResult.successful(rv, returnType != null && KotlinBuiltIns.isUnit(returnType)); } catch (Throwable e) { @SuppressWarnings("UseOfSystemOutOrSystemErr") PrintWriter writer = new PrintWriter(System.err); classLoader.dumpClasses(writer); writer.flush(); throw UtilsPackage.rethrow(e); } }
@NotNull @Override public RuntimeException handleException(@NotNull Throwable throwable) { throw UtilsPackage.rethrow(throwable); }