KotlinLightClassBuilderFactory, LightClassBuilder: refactor, clarify

This commit is contained in:
Pavel V. Talanov
2017-03-14 16:20:54 +03:00
parent c73e58516b
commit a645dc109a
4 changed files with 62 additions and 86 deletions
@@ -1,60 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.asJava.builder;
import com.intellij.psi.stubs.StubElement;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.codegen.ClassBuilder;
import org.jetbrains.kotlin.codegen.ClassBuilderFactory;
import org.jetbrains.kotlin.codegen.ClassBuilderMode;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
/*package*/ class KotlinLightClassBuilderFactory implements ClassBuilderFactory {
private final Stack<StubElement> stubStack;
public KotlinLightClassBuilderFactory(Stack<StubElement> stubStack) {
this.stubStack = stubStack;
}
@NotNull
@Override
public ClassBuilderMode getClassBuilderMode() {
return ClassBuilderMode.LIGHT_CLASSES;
}
@NotNull
@Override
public ClassBuilder newClassBuilder(@NotNull JvmDeclarationOrigin origin) {
return new StubClassBuilder(stubStack);
}
@Override
public String asText(ClassBuilder builder) {
throw new UnsupportedOperationException("asText is not implemented"); // TODO
}
@Override
public byte[] asBytes(ClassBuilder builder) {
throw new UnsupportedOperationException("asBytes is not implemented"); // TODO
}
@Override
public void close() {
}
}
@@ -0,0 +1,51 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.asJava.builder
import com.intellij.openapi.diagnostic.Logger
import com.intellij.psi.PsiElement
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
import com.intellij.psi.stubs.StubElement
import com.intellij.util.containers.Stack
import org.jetbrains.kotlin.codegen.ClassBuilder
import org.jetbrains.kotlin.codegen.ClassBuilderFactory
import org.jetbrains.kotlin.codegen.ClassBuilderMode
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
class KotlinLightClassBuilderFactory(private val javaFileStub: PsiJavaFileStub) : ClassBuilderFactory {
private val stubStack = Stack<StubElement<PsiElement>>().apply {
@Suppress("UNCHECKED_CAST")
push(javaFileStub as StubElement<PsiElement>)
}
override fun getClassBuilderMode(): ClassBuilderMode = ClassBuilderMode.LIGHT_CLASSES
override fun newClassBuilder(origin: JvmDeclarationOrigin) = StubClassBuilder(stubStack, javaFileStub)
override fun asText(builder: ClassBuilder) = throw UnsupportedOperationException("asText is not implemented")
override fun asBytes(builder: ClassBuilder) = throw UnsupportedOperationException("asBytes is not implemented")
override fun close() {}
fun result(): PsiJavaFileStub {
val pop = stubStack.pop()
if (pop !== javaFileStub) {
LOG.error("Unbalanced stack operations: " + pop)
}
return javaFileStub
}
}
private val LOG = Logger.getInstance(KotlinLightClassBuilderFactory::class.java)
@@ -23,13 +23,10 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.util.SystemInfo
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.ClassFileViewProvider
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiManager
import com.intellij.psi.impl.compiled.ClsFileImpl
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
import com.intellij.psi.impl.java.stubs.impl.PsiJavaFileStubImpl
import com.intellij.psi.stubs.StubElement
import com.intellij.util.containers.Stack
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.name.FqName
@@ -47,20 +44,12 @@ fun buildLightClass(
generate: (state: GenerationState, files: Collection<KtFile>) -> Unit
): LightClassBuilderResult {
val project = files.first().project
val javaFileStub = createJavaFileStub(project, packageFqName, files)
val bindingContext: BindingContext
val state: GenerationState
try {
val stubStack = Stack<StubElement<PsiElement>>()
@Suppress("UNCHECKED_CAST")
stubStack.push(javaFileStub as StubElement<PsiElement>)
state = GenerationState(
val classBuilderFactory = KotlinLightClassBuilderFactory(createJavaFileStub(project, packageFqName, files))
val state = GenerationState(
project,
KotlinLightClassBuilderFactory(stubStack),
classBuilderFactory,
context.module,
context.bindingContext,
files.toList(),
@@ -70,17 +59,12 @@ fun buildLightClass(
)
state.beforeCompile()
bindingContext = state.bindingContext
generate(state, files)
val pop = stubStack.pop()
if (pop !== javaFileStub) {
LOG.error("Unbalanced stack operations: " + pop)
}
val javaFileStub = classBuilderFactory.result()
ServiceManager.getService(project, StubComputationTracker::class.java)?.onStubComputed(javaFileStub, context)
return LightClassBuilderResult(javaFileStub, bindingContext, state.collectedExtraJvmDiagnostics)
return LightClassBuilderResult(javaFileStub, context.bindingContext, state.collectedExtraJvmDiagnostics)
}
catch (e: ProcessCanceledException) {
throw e
@@ -50,14 +50,16 @@ public class StubClassBuilder extends AbstractClassBuilder {
}
};
private final StubElement parent;
private final PsiJavaFileStub fileStub;
private StubBuildingVisitor v;
private final Stack<StubElement> parentStack;
private boolean isPackageClass = false;
private int memberIndex = 0;
public StubClassBuilder(@NotNull Stack<StubElement> parentStack) {
public StubClassBuilder(@NotNull Stack<StubElement> parentStack, @NotNull PsiJavaFileStub fileStub) {
this.parentStack = parentStack;
this.parent = parentStack.peek();
this.fileStub = fileStub;
}
@NotNull
@@ -102,7 +104,8 @@ public class StubClassBuilder extends AbstractClassBuilder {
@Nullable
private String calculateShortName(@NotNull String internalName) {
if (parent instanceof PsiJavaFileStub) {
String packagePrefix = getPackageInternalNamePrefix((PsiJavaFileStub) parent);
assert parent == fileStub;
String packagePrefix = getPackageInternalNamePrefix();
assert internalName.startsWith(packagePrefix) : internalName + " : " + packagePrefix;
return internalName.substring(packagePrefix.length());
}
@@ -118,8 +121,6 @@ public class StubClassBuilder extends AbstractClassBuilder {
@Nullable
private String getClassInternalNamePrefix(@NotNull PsiClassStub classStub) {
PsiJavaFileStub fileStub = (PsiJavaFileStub) parentStack.get(0);
String packageName = fileStub.getPackageName();
String classStubQualifiedName = classStub.getQualifiedName();
@@ -135,7 +136,7 @@ public class StubClassBuilder extends AbstractClassBuilder {
@NotNull
private static String getPackageInternalNamePrefix(@NotNull PsiJavaFileStub fileStub) {
private String getPackageInternalNamePrefix() {
String packageName = fileStub.getPackageName();
if (packageName.isEmpty()) {
return "";