partial support for 'abstract' modifier added
This commit is contained in:
@@ -43,4 +43,8 @@ public interface ClassDescriptor extends ClassifierDescriptor {
|
||||
JetType getClassObjectType();
|
||||
|
||||
boolean isObject();
|
||||
|
||||
boolean isAbstract();
|
||||
|
||||
boolean isOpen();
|
||||
}
|
||||
|
||||
@@ -115,4 +115,14 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
|
||||
public boolean hasConstructors() {
|
||||
return !constructors.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,11 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MemberModifiers getModifiers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOverriddenFunction(@NotNull FunctionDescriptor overriddenFunction) {
|
||||
throw new UnsupportedOperationException("Constructors cannot override anything");
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.util.Set;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface FunctionDescriptor extends DeclarationDescriptor {
|
||||
public interface FunctionDescriptor extends DeclarationDescriptor, MemberDescriptor {
|
||||
@Override
|
||||
@NotNull
|
||||
DeclarationDescriptor getContainingDeclaration();
|
||||
|
||||
@@ -22,6 +22,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
||||
private JetType unsubstitutedReturnType;
|
||||
private JetType receiverType;
|
||||
|
||||
private MemberModifiers modifiers;
|
||||
private final Set<FunctionDescriptor> overriddenFunctions = Sets.newHashSet();
|
||||
private final FunctionDescriptor original;
|
||||
|
||||
@@ -68,6 +69,16 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
||||
return overriddenFunctions;
|
||||
}
|
||||
|
||||
public void setModifiers(MemberModifiers modifiers) {
|
||||
this.modifiers = modifiers;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MemberModifiers getModifiers() {
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
public void addOverriddenFunction(@NotNull FunctionDescriptor overriddenFunction) {
|
||||
overriddenFunctions.add(overriddenFunction);
|
||||
}
|
||||
|
||||
@@ -126,6 +126,16 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
|
||||
return original.isObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return original.isAbstract();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return original.isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClassObjectAValue() {
|
||||
return original.isClassObjectAValue();
|
||||
|
||||
@@ -23,6 +23,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
|
||||
private Collection<JetType> supertypes = Lists.newArrayList();
|
||||
|
||||
private boolean open;
|
||||
private boolean isAbstract;
|
||||
private TypeConstructor typeConstructor;
|
||||
private final WritableScope scopeForMemberResolution;
|
||||
private final WritableScope scopeForMemberLookup;
|
||||
@@ -139,6 +140,15 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
|
||||
scopeForMemberResolution.addLabeledDeclaration(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return isAbstract;
|
||||
}
|
||||
|
||||
public void setAbstract(boolean isAbstract) {
|
||||
this.isAbstract = isAbstract;
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return open;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ public interface BindingContext {
|
||||
WritableSlice<JetExpression, JetScope> RESOLUTION_SCOPE = ManyMapSlices.createSimpleSlice("RESOLUTION_SCOPE");
|
||||
|
||||
WritableSlice<JetExpression, Boolean> VARIABLE_REASSIGNMENT = ManyMapSlices.createSimpleSetSlice("VARIABLE_REASSIGNMENT");
|
||||
WritableSlice<JetExpression, DeclarationDescriptor> VARIABLE_ASSIGNMENT = ManyMapSlices.createSimpleSlice("VARIABLE_ASSIGNMENT");
|
||||
WritableSlice<JetExpression, Boolean> PROCESSED = ManyMapSlices.createSimpleSetSlice("PROCESSED");
|
||||
WritableSlice<JetElement, Boolean> STATEMENT = ManyMapSlices.createRemovableSetSlice("STATEMENT");
|
||||
|
||||
@@ -59,6 +60,7 @@ public interface BindingContext {
|
||||
return backingFieldRequired;
|
||||
}
|
||||
};
|
||||
WritableSlice<PropertyDescriptor, Boolean> IS_INITIALIZED = ManyMapSlices.createSimpleSetSlice("IS_INITIALIZED");
|
||||
|
||||
WritableSlice<JetFunctionLiteralExpression, Boolean> BLOCK = new ManyMapSlices.SetSlice<JetFunctionLiteralExpression>("BLOCK", RewritePolicy.DO_NOTHING) {
|
||||
@Override
|
||||
|
||||
@@ -65,6 +65,11 @@ public class ClassDescriptorResolver {
|
||||
Collection<JetType> supertypes = delegationSpecifiers.isEmpty()
|
||||
? Collections.singleton(JetStandardClasses.getAnyType())
|
||||
: resolveDelegationSpecifiers(parameterScope, delegationSpecifiers, typeResolver);
|
||||
// for (JetType supertype: supertypes) {
|
||||
// if (supertype.getConstructor().isSealed()) {
|
||||
// trace.getErrorHandler().genericError(classElement.getNameAsDeclaration().getNode(), "Class " + classElement.getName() + " can not extend final type " + supertype);
|
||||
// }
|
||||
// }
|
||||
boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD);
|
||||
|
||||
final WritableScope memberDeclarations = new WritableScopeImpl(parameterScope, classDescriptor, trace.getErrorHandler());
|
||||
@@ -141,6 +146,7 @@ public class ClassDescriptorResolver {
|
||||
descriptor.setTypeParameterDescriptors(typeParameters);
|
||||
|
||||
descriptor.setOpen(classElement.hasModifier(JetTokens.OPEN_KEYWORD) || classElement.hasModifier(JetTokens.ABSTRACT_KEYWORD));
|
||||
descriptor.setAbstract(classElement.hasModifier(JetTokens.ABSTRACT_KEYWORD));
|
||||
|
||||
trace.record(BindingContext.CLASS, classElement, descriptor);
|
||||
}
|
||||
@@ -220,6 +226,7 @@ public class ClassDescriptorResolver {
|
||||
returnType = ErrorUtils.createErrorType("No type, no body");
|
||||
}
|
||||
}
|
||||
functionDescriptor.setModifiers(resolveModifiers(function.getModifierList(), DEFAULT_MODIFIERS));
|
||||
|
||||
functionDescriptor.initialize(
|
||||
receiverType,
|
||||
|
||||
@@ -27,8 +27,9 @@ public class TopDownAnalyzer {
|
||||
|
||||
private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap();
|
||||
private final Map<JetObjectDeclaration, MutableClassDescriptor> objects = Maps.newLinkedHashMap();
|
||||
private final Map<JetNamespace, WritableScope> namespaceScopes = Maps.newHashMap();
|
||||
private final Map<JetNamespace, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap();
|
||||
|
||||
protected final Map<JetNamespace, WritableScope> namespaceScopes = Maps.newHashMap();
|
||||
protected final Map<JetNamespace, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap();
|
||||
|
||||
private final Map<JetNamedFunction, FunctionDescriptorImpl> functions = Maps.newLinkedHashMap();
|
||||
private final Map<JetDeclaration, ConstructorDescriptor> constructors = Maps.newLinkedHashMap();
|
||||
@@ -76,46 +77,39 @@ public class TopDownAnalyzer {
|
||||
});
|
||||
}
|
||||
|
||||
@Deprecated // For JetStandardLibraryOnly
|
||||
public void processStandardLibraryNamespace(@NotNull WritableScope outerScope, @NotNull NamespaceDescriptorImpl standardLibraryNamespace, @NotNull JetNamespace namespace) {
|
||||
namespaceScopes.put(namespace, standardLibraryNamespace.getMemberScope());
|
||||
namespaceDescriptors.put(namespace, standardLibraryNamespace);
|
||||
process(outerScope, standardLibraryNamespace, namespace.getDeclarations());
|
||||
}
|
||||
|
||||
public void processObject(@NotNull JetScope outerScope, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetObjectDeclaration object) {
|
||||
process(outerScope, new NamespaceLike.Adapter(containingDeclaration) {
|
||||
|
||||
@Override
|
||||
public NamespaceDescriptorImpl getNamespace(String name) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@Override
|
||||
public NamespaceDescriptorImpl getNamespace(String name) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@Override
|
||||
public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) {
|
||||
@Override
|
||||
public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@Override
|
||||
public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
@Override
|
||||
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
|
||||
return ClassObjectStatus.NOT_ALLOWED;
|
||||
}
|
||||
}, Collections.<JetDeclaration>singletonList(object));
|
||||
@Override
|
||||
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
|
||||
return ClassObjectStatus.NOT_ALLOWED;
|
||||
}
|
||||
}, Collections.<JetDeclaration>singletonList(object));
|
||||
}
|
||||
|
||||
public void process(@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List<JetDeclaration> declarations) {
|
||||
@@ -414,6 +408,7 @@ public class TopDownAnalyzer {
|
||||
@Override
|
||||
public void visitNamedFunction(JetNamedFunction function) {
|
||||
FunctionDescriptorImpl functionDescriptor = classDescriptorResolver.resolveFunctionDescriptor(namespaceLike, scope, function);
|
||||
checkFunctionCorrectness(function, functionDescriptor, namespaceLike);
|
||||
namespaceLike.addFunctionDescriptor(functionDescriptor);
|
||||
functions.put(function, functionDescriptor);
|
||||
declaringScopes.put(function, scope);
|
||||
@@ -505,12 +500,29 @@ public class TopDownAnalyzer {
|
||||
private void bindOverridesInAClass(MutableClassDescriptor classDescriptor) {
|
||||
|
||||
for (FunctionDescriptor declaredFunction : classDescriptor.getFunctions()) {
|
||||
// JetFunction function = (JetFunction) trace.get(BindingContext.DESCRIPTOR_TO_DECLARATION, declaredFunction);
|
||||
// boolean isOverride = declaredFunction.getModifiers().isOverride();
|
||||
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
|
||||
FunctionDescriptor overridden = findFunctionOverridableBy(declaredFunction, supertype);
|
||||
if (overridden != null) {
|
||||
// if (isOverride && overridden.getModifiers()!= null && !overridden.getModifiers().isOverridable()) {
|
||||
// trace.getErrorHandler().genericError(function.getModifierList().getModifierNode(JetTokens.OVERRIDE_KEYWORD),
|
||||
// "Method " + overridden.getName() + " in " + overridden.getContainingDeclaration().getName() + " is final and can not be overridden");
|
||||
// isOverride = false;
|
||||
// }
|
||||
((FunctionDescriptorImpl) declaredFunction).addOverriddenFunction(overridden);
|
||||
}
|
||||
}
|
||||
// if (declaredFunction.getModifiers().isOverride() && declaredFunction.getOverriddenFunctions().size() == 0) {
|
||||
// trace.getErrorHandler().genericError(function.getModifierList().getModifierNode(JetTokens.OVERRIDE_KEYWORD),
|
||||
// "Method " + declaredFunction.getName() + " overrides nothing");
|
||||
// }
|
||||
// if (!declaredFunction.getModifiers().isOverride() && declaredFunction.getOverriddenFunctions().size() > 0) {
|
||||
// FunctionDescriptor overriddenMethod = declaredFunction.getOverriddenFunctions().iterator().next();
|
||||
// trace.getErrorHandler().genericError(function.getNameIdentifier().getNode(),
|
||||
// "Method " + declaredFunction.getName() + " overrides method " + overriddenMethod.getName() + " in class " +
|
||||
// overriddenMethod.getContainingDeclaration().getName() + " and needs 'override' modifier");
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -567,7 +579,9 @@ public class TopDownAnalyzer {
|
||||
public void visitDelegationByExpressionSpecifier(JetDelegatorByExpressionSpecifier specifier) {
|
||||
JetExpression delegateExpression = specifier.getDelegateExpression();
|
||||
if (delegateExpression != null) {
|
||||
JetScope scope = scopeForConstructor == null ? descriptor.getScopeForMemberResolution() : scopeForConstructor;
|
||||
JetScope scope = scopeForConstructor == null
|
||||
? descriptor.getScopeForMemberResolution()
|
||||
: scopeForConstructor;
|
||||
JetType type = typeInferrer.getType(scope, delegateExpression, false, JetTypeInferrer.NO_EXPECTED_TYPE);
|
||||
JetType supertype = trace.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
|
||||
if (type != null && !semanticServices.getTypeChecker().isSubtypeOf(type, supertype)) { // TODO : Convertible?
|
||||
@@ -587,7 +601,7 @@ public class TopDownAnalyzer {
|
||||
JetValueArgumentList valueArgumentList = call.getValueArgumentList();
|
||||
assert valueArgumentList != null;
|
||||
trace.getErrorHandler().genericError(valueArgumentList.getNode(),
|
||||
"Class " + JetPsiUtil.safeName(jetClass.getName()) + " must have a constructor in order to be able to initialize supertypes");
|
||||
"Class " + JetPsiUtil.safeName(jetClass.getName()) + " must have a constructor in order to be able to initialize supertypes");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -642,7 +656,7 @@ public class TopDownAnalyzer {
|
||||
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
|
||||
assert primaryConstructor != null;
|
||||
final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
|
||||
JetTypeInferrer.Services typeInferrer = semanticServices.getTypeInferrerServices(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
|
||||
JetTypeInferrer.Services typeInferrer = semanticServices.getTypeInferrerServices(createFieldAssignTrackingTrace(), JetFlowInformationProvider.NONE); // TODO : flow
|
||||
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
|
||||
typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), true, JetTypeInferrer.NO_EXPECTED_TYPE);
|
||||
}
|
||||
@@ -782,6 +796,7 @@ public class TopDownAnalyzer {
|
||||
}
|
||||
|
||||
resolvePropertyAccessors(property, propertyDescriptor, declaringScope);
|
||||
checkPropertyCorrectness(property, propertyDescriptor, classDescriptor);
|
||||
processed.add(property);
|
||||
}
|
||||
}
|
||||
@@ -800,6 +815,7 @@ public class TopDownAnalyzer {
|
||||
}
|
||||
|
||||
resolvePropertyAccessors(property, propertyDescriptor, declaringScope);
|
||||
checkPropertyCorrectness(property, propertyDescriptor, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -833,9 +849,69 @@ public class TopDownAnalyzer {
|
||||
resolveFunctionBody(fieldAccessTrackingTrace, setter, setterDescriptor, accessorScope);
|
||||
}
|
||||
|
||||
// JetExpression initializer = property.getInitializer();
|
||||
// if (!property.isVar() && initializer != null && !trace.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
|
||||
// trace.getErrorHandler().genericError(initializer.getNode(), "Initializer is not allowed here because this property has no setter and no backing field either");
|
||||
// }
|
||||
}
|
||||
|
||||
protected void checkPropertyCorrectness(JetProperty property, PropertyDescriptor propertyDescriptor, @Nullable ClassDescriptor classDescriptor) {
|
||||
JetExpression initializer = property.getInitializer();
|
||||
if (!property.isVar() && initializer != null && !trace.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
|
||||
trace.getErrorHandler().genericError(initializer.getNode(), "Initializer is not allowed here because this property has no setter and no backing field either");
|
||||
JetPropertyAccessor getter = property.getGetter();
|
||||
JetPropertyAccessor setter = property.getSetter();
|
||||
if (propertyDescriptor.getModifiers().isAbstract()) {
|
||||
if (classDescriptor == null) {
|
||||
trace.getErrorHandler().genericError(property.getModifierList().getModifierNode(JetTokens.ABSTRACT_KEYWORD),
|
||||
"Global property can not be abstract");
|
||||
return;
|
||||
}
|
||||
if (! classDescriptor.isAbstract()) {
|
||||
trace.getErrorHandler().genericError(property.getModifierList().getModifierNode(JetTokens.ABSTRACT_KEYWORD),
|
||||
"Abstract property " + property.getName() + " in non-abstract class " + classDescriptor.getName());
|
||||
return;
|
||||
}
|
||||
if (initializer != null) {
|
||||
trace.getErrorHandler().genericError(initializer.getNode(), "Property with initializer can not be abstract");
|
||||
}
|
||||
if (getter != null && getter.getBodyExpression() != null) {
|
||||
trace.getErrorHandler().genericError(getter.getNode(), "Property with getter implementation can not be abstract");
|
||||
}
|
||||
if (setter != null && setter.getBodyExpression() != null) {
|
||||
trace.getErrorHandler().genericError(setter.getNode(), "Property with setter implementation can not be abstract");
|
||||
}
|
||||
return;
|
||||
}
|
||||
boolean backingFieldRequired = trace.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor);
|
||||
if (initializer != null && ! backingFieldRequired) {
|
||||
trace.getErrorHandler().genericError(initializer.getNode(), "Initializer is not allowed here because this property has no backing field");
|
||||
}
|
||||
if (initializer == null && backingFieldRequired && ! trace.getBindingContext().get(BindingContext.IS_INITIALIZED, propertyDescriptor)) {
|
||||
if (classDescriptor == null || (getter != null && getter.getBodyExpression() != null) || (setter != null && setter.getBodyExpression() != null)) {
|
||||
trace.getErrorHandler().genericError(property.getNameIdentifier().getNode(), "Property must be initialized");
|
||||
} else {
|
||||
trace.getErrorHandler().genericError(property.getNameIdentifier().getNode(), "Property must be initialized or be abstract");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkFunctionCorrectness(JetNamedFunction function, FunctionDescriptor functionDescriptor, DeclarationDescriptor containingDescriptor) {
|
||||
if (containingDescriptor instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDescriptor;
|
||||
if (functionDescriptor.getModifiers().isAbstract() && !classDescriptor.isAbstract()) {
|
||||
trace.getErrorHandler().genericError(function.getModifierList().getModifierNode(JetTokens.ABSTRACT_KEYWORD),
|
||||
"Abstract method " + function.getName() + " in non-abstract class " + classDescriptor.getName());
|
||||
}
|
||||
if (function.getBodyExpression() == null && !functionDescriptor.getModifiers().isAbstract()) {
|
||||
trace.getErrorHandler().genericError(function.getNameIdentifier().getNode(), "Method without body must be abstract");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (functionDescriptor.getModifiers().isAbstract()) {
|
||||
trace.getErrorHandler().genericError(function.getModifierList().getModifierNode(JetTokens.ABSTRACT_KEYWORD),
|
||||
"Global function " + function.getName() + " can not be abstract");
|
||||
}
|
||||
if (function.getBodyExpression() == null && !functionDescriptor.getModifiers().isAbstract()) {
|
||||
trace.getErrorHandler().genericError(function.getNameIdentifier().getNode(), "Global function must have body");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -856,6 +932,22 @@ public class TopDownAnalyzer {
|
||||
});
|
||||
}
|
||||
|
||||
private BindingTraceAdapter createFieldAssignTrackingTrace() {
|
||||
return new BindingTraceAdapter(traceForConstructors).addHandler(BindingContext.VARIABLE_ASSIGNMENT, new BindingTraceAdapter.RecordHandler<JetExpression, DeclarationDescriptor>() {
|
||||
@Override
|
||||
public void handleRecord(WritableSlice<JetExpression, DeclarationDescriptor> jetExpressionBooleanWritableSlice, JetExpression expression, DeclarationDescriptor descriptor) {
|
||||
if (expression instanceof JetSimpleNameExpression) {
|
||||
JetSimpleNameExpression variable = (JetSimpleNameExpression) expression;
|
||||
if (variable.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) {
|
||||
if (descriptor instanceof PropertyDescriptor) {
|
||||
traceForMembers.record(BindingContext.IS_INITIALIZED, (PropertyDescriptor) descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) {
|
||||
JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(property, initializer); // TODO : flow JET-15
|
||||
JetTypeInferrer.Services typeInferrer = semanticServices.getTypeInferrerServices(traceForConstructors, flowInformationProvider);
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.JetNamedFunction;
|
||||
import org.jetbrains.jet.lang.psi.JetNamespace;
|
||||
import org.jetbrains.jet.lang.psi.JetProperty;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class TopDownAnalyzerForStandardLibrary extends TopDownAnalyzer {
|
||||
|
||||
public TopDownAnalyzerForStandardLibrary(JetSemanticServices semanticServices, @NotNull BindingTrace bindingTrace) {
|
||||
super(semanticServices, bindingTrace);
|
||||
}
|
||||
|
||||
public void processStandardLibraryNamespace(@NotNull WritableScope outerScope, @NotNull NamespaceDescriptorImpl standardLibraryNamespace, @NotNull JetNamespace namespace) {
|
||||
namespaceScopes.put(namespace, standardLibraryNamespace.getMemberScope());
|
||||
namespaceDescriptors.put(namespace, standardLibraryNamespace);
|
||||
process(outerScope, standardLibraryNamespace, namespace.getDeclarations());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkPropertyCorrectness(JetProperty property, PropertyDescriptor propertyDescriptor, ClassDescriptor classDescriptor) {}
|
||||
|
||||
|
||||
@Override
|
||||
protected void checkFunctionCorrectness(JetNamedFunction function, FunctionDescriptor functionDescriptor, DeclarationDescriptor containingDescriptor) {}
|
||||
}
|
||||
@@ -115,6 +115,16 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClassObjectAValue() {
|
||||
return false;
|
||||
|
||||
@@ -81,7 +81,7 @@ public class JetStandardLibrary {
|
||||
|
||||
JetSemanticServices bootstrappingSemanticServices = JetSemanticServices.createSemanticServices(this);
|
||||
BindingTraceContext bindingTraceContext = new BindingTraceContext();
|
||||
TopDownAnalyzer bootstrappingTDA = new TopDownAnalyzer(bootstrappingSemanticServices, bindingTraceContext);
|
||||
TopDownAnalyzerForStandardLibrary bootstrappingTDA = new TopDownAnalyzerForStandardLibrary(bootstrappingSemanticServices, bindingTraceContext);
|
||||
WritableScopeImpl writableScope = new WritableScopeImpl(JetStandardClasses.STANDARD_CLASSES, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, ErrorHandler.THROW_EXCEPTION).setDebugName("Root bootstrap scope");
|
||||
// this.libraryScope = bootstrappingTDA.process(JetStandardClasses.STANDARD_CLASSES, file.getRootNamespace().getDeclarations());
|
||||
// bootstrappingTDA.process(writableScope, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, file.getRootNamespace().getDeclarations());
|
||||
|
||||
@@ -2806,6 +2806,17 @@ public class JetTypeInferrer {
|
||||
// context.trace.getErrorHandler().typeMismatch(right, leftType, rightType);
|
||||
// }
|
||||
}
|
||||
if (left instanceof JetSimpleNameExpression) {
|
||||
JetSimpleNameExpression variable = (JetSimpleNameExpression) left;
|
||||
String referencedName = variable.getReferencedName();
|
||||
if (variable.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER
|
||||
&& referencedName != null) {
|
||||
PropertyDescriptor property = context.scope.getPropertyByFieldReference(referencedName);
|
||||
if (property != null) {
|
||||
context.trace.record(BindingContext.VARIABLE_ASSIGNMENT, variable, property);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
namespace abstract
|
||||
|
||||
class A1() {
|
||||
fun <error>foo</error>(): Int
|
||||
<error>abstract</error> fun f(): Int
|
||||
}
|
||||
|
||||
abstract class A2() {
|
||||
abstract fun f(): Int
|
||||
}
|
||||
|
||||
class A3() {
|
||||
val <error>i</error>: Int
|
||||
val <error>j</error>: Int?
|
||||
var <error>k</error>: String
|
||||
var <error>l</error>: Int?
|
||||
}
|
||||
|
||||
class <error>A4</error> {
|
||||
val <error>i</error>: Int?
|
||||
}
|
||||
|
||||
class <error>A5</error> {
|
||||
var <error>i</error>: Int?
|
||||
}
|
||||
|
||||
class A6 {
|
||||
<error>abstract</error> val i: Int
|
||||
}
|
||||
|
||||
abstract class A7 {
|
||||
abstract val i: Int //ok
|
||||
}
|
||||
|
||||
class A8() {
|
||||
val i = 11
|
||||
}
|
||||
|
||||
class A9() {
|
||||
<error>abstract</error> val i = 23
|
||||
}
|
||||
|
||||
abstract class <error>A10</error> {
|
||||
val <error>i</error>: Int
|
||||
}
|
||||
|
||||
<error>abstract</error> val i: Int
|
||||
<error>abstract</error> fun foo(): fun(Int): Int
|
||||
val <error>j</error>: Int
|
||||
fun <error>foo1</error>(): fun(Int): Int
|
||||
@@ -1,13 +1,13 @@
|
||||
class A() {
|
||||
fun equals(a : Any?) : Boolean
|
||||
abstract class A() {
|
||||
abstract fun equals(a : Any?) : Boolean
|
||||
}
|
||||
|
||||
class B() {
|
||||
fun equals(a : Any?) : Boolean?
|
||||
abstract class B() {
|
||||
abstract fun equals(a : Any?) : Boolean?
|
||||
}
|
||||
|
||||
class C() {
|
||||
fun equals(a : Any?) : Int
|
||||
abstract class C() {
|
||||
abstract fun equals(a : Any?) : Int
|
||||
}
|
||||
|
||||
fun f(): Unit {
|
||||
|
||||
@@ -18,10 +18,10 @@ namespace boundsWithSubstitutors {
|
||||
open class A {}
|
||||
open class B<T : A>()
|
||||
|
||||
class C<T : B<<error>Int</error>>, X : fun (B<<error>Char</error>>) : (B<<error>Any</error>>, B<A>)>() : B<<error>Any</error>>() { // 2 errors
|
||||
abstract class C<T : B<<error>Int</error>>, X : fun (B<<error>Char</error>>) : (B<<error>Any</error>>, B<A>)>() : B<<error>Any</error>>() { // 2 errors
|
||||
val a = B<<error>Char</error>>() // error
|
||||
|
||||
val x : fun (B<<error>Char</error>>) : B<<error>Any</error>>
|
||||
abstract val x : fun (B<<error>Char</error>>) : B<<error>Any</error>>
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fun Int?.optint() : Unit
|
||||
val Int?.optval : Unit
|
||||
fun Int?.optint() : Unit {}
|
||||
val Int?.optval : Unit = ()
|
||||
|
||||
fun <T, E> T.foo(x : E, y : A) : T {
|
||||
y.plus(1)
|
||||
@@ -33,20 +33,20 @@ fun test() {
|
||||
val Int.abs : Int
|
||||
get() = if (this > 0) this else -this;
|
||||
|
||||
val <T> T.foo : T
|
||||
val <T> T.<error>foo</error> : T
|
||||
|
||||
fun Int.foo() = this
|
||||
|
||||
namespace null_safety {
|
||||
|
||||
fun parse(cmd: String): Command? { return null }
|
||||
class Command() {
|
||||
abstract class Command() {
|
||||
// fun equals(other : Any?) : Boolean
|
||||
val foo : Int
|
||||
abstract val foo : Int
|
||||
}
|
||||
|
||||
fun Any.equals(other : Any?) : Boolean
|
||||
fun Any?.equals1(other : Any?) : Boolean
|
||||
fun Any.equals(other : Any?) : Boolean = true
|
||||
fun Any?.equals1(other : Any?) : Boolean = true
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
|
||||
@@ -4,65 +4,65 @@ class NotRange1() {
|
||||
|
||||
}
|
||||
|
||||
class NotRange2() {
|
||||
fun iterator() : Unit
|
||||
abstract class NotRange2() {
|
||||
abstract fun iterator() : Unit
|
||||
}
|
||||
|
||||
class ImproperIterator1 {
|
||||
fun hasNext() : Boolean
|
||||
abstract class ImproperIterator1 {
|
||||
abstract fun hasNext() : Boolean
|
||||
}
|
||||
|
||||
class NotRange3() {
|
||||
fun iterator() : ImproperIterator1
|
||||
abstract class NotRange3() {
|
||||
abstract fun iterator() : ImproperIterator1
|
||||
}
|
||||
|
||||
class ImproperIterator2 {
|
||||
fun next() : Boolean
|
||||
abstract class ImproperIterator2 {
|
||||
abstract fun next() : Boolean
|
||||
}
|
||||
|
||||
class NotRange4() {
|
||||
fun iterator() : ImproperIterator2
|
||||
abstract class NotRange4() {
|
||||
abstract fun iterator() : ImproperIterator2
|
||||
}
|
||||
|
||||
class ImproperIterator3 {
|
||||
fun hasNext() : Int
|
||||
fun next() : Int
|
||||
abstract class ImproperIterator3 {
|
||||
abstract fun hasNext() : Int
|
||||
abstract fun next() : Int
|
||||
}
|
||||
|
||||
class NotRange5() {
|
||||
fun iterator() : ImproperIterator3
|
||||
abstract class NotRange5() {
|
||||
abstract fun iterator() : ImproperIterator3
|
||||
}
|
||||
|
||||
class AmbiguousHasNextIterator {
|
||||
fun hasNext() : Boolean
|
||||
abstract class AmbiguousHasNextIterator {
|
||||
abstract fun hasNext() : Boolean
|
||||
val hasNext : Boolean get() = false
|
||||
fun next() : Int
|
||||
abstract fun next() : Int
|
||||
}
|
||||
|
||||
class NotRange6() {
|
||||
fun iterator() : AmbiguousHasNextIterator
|
||||
abstract class NotRange6() {
|
||||
abstract fun iterator() : AmbiguousHasNextIterator
|
||||
}
|
||||
|
||||
class ImproperIterator4 {
|
||||
abstract class ImproperIterator4 {
|
||||
val hasNext : Int get() = 1
|
||||
fun next() : Int
|
||||
abstract fun next() : Int
|
||||
}
|
||||
|
||||
class NotRange7() {
|
||||
fun iterator() : ImproperIterator3
|
||||
abstract class NotRange7() {
|
||||
abstract fun iterator() : ImproperIterator3
|
||||
}
|
||||
|
||||
class GoodIterator {
|
||||
fun hasNext() : Boolean
|
||||
fun next() : Int
|
||||
abstract class GoodIterator {
|
||||
abstract fun hasNext() : Boolean
|
||||
abstract fun next() : Int
|
||||
}
|
||||
|
||||
class Range0() {
|
||||
fun iterator() : GoodIterator
|
||||
abstract class Range0() {
|
||||
abstract fun iterator() : GoodIterator
|
||||
}
|
||||
|
||||
class Range1() {
|
||||
fun iterator() : Iterator<Int>
|
||||
abstract class Range1() {
|
||||
abstract fun iterator() : Iterator<Int>
|
||||
}
|
||||
|
||||
fun test() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
fun none()
|
||||
fun none() {}
|
||||
|
||||
fun unitEmptyInfer() {}
|
||||
fun unitEmpty() : Unit {}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
namespace Jet87
|
||||
|
||||
open class A() {
|
||||
fun foo() : Int
|
||||
fun foo() : Int = 1
|
||||
}
|
||||
|
||||
open class B() {
|
||||
fun bar() : Double;
|
||||
fun bar() : Double = 1.0;
|
||||
}
|
||||
|
||||
class C() : A(), B()
|
||||
@@ -69,4 +69,4 @@ class Test<<error>T</error>>
|
||||
class object T : <error>Foo</error>,
|
||||
class object T : A {}
|
||||
|
||||
val <T, B : T> x : Int
|
||||
val <T, B : T> x : Int = 0
|
||||
@@ -22,22 +22,29 @@ val y1 = a.b
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
fun done<O>(result : O) : Iteratee<Any?, O>
|
||||
fun done<O>(result : O) : Iteratee<Any?, O> = StrangeIterateeImpl<Any?, O>(result)
|
||||
|
||||
class Iteratee<in I, out O> {
|
||||
abstract class Iteratee<in I, out O> {
|
||||
abstract fun process(item : I) : Iteratee<I, O>
|
||||
abstract val isDone : Boolean
|
||||
abstract val result : O
|
||||
abstract fun done() : O
|
||||
}
|
||||
|
||||
class Sum() : Iteratee<Int, Int> {
|
||||
class StrangeIterateeImpl<in I, out O>(val obj: O) : Iteratee<I, O> {
|
||||
override fun process(item: I): Iteratee<I, O> = StrangeIterateeImpl<I, O>(obj)
|
||||
override val isDone = true
|
||||
override val result = obj
|
||||
override val done = obj
|
||||
}
|
||||
|
||||
abstract class Sum() : Iteratee<Int, Int> {
|
||||
override fun process(item : Int) : Iteratee<Int, Int> {
|
||||
return foobar.done<Int>(item);
|
||||
}
|
||||
override val isDone : Boolean
|
||||
override val result : Int
|
||||
override fun done() : Int
|
||||
abstract override val isDone : Boolean
|
||||
abstract override val result : Int
|
||||
abstract override fun done() : Int
|
||||
}
|
||||
|
||||
class Collection<E> : Iterable<E> {
|
||||
|
||||
@@ -60,11 +60,11 @@ namespace nestedObejcts {
|
||||
|
||||
namespace localObjects {
|
||||
object A {
|
||||
val x : Int
|
||||
val x : Int = 0
|
||||
}
|
||||
|
||||
class Foo {
|
||||
fun foo() : Int
|
||||
fun foo() : Int = 1
|
||||
}
|
||||
|
||||
fun test() {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
class <error>X</error> {
|
||||
val x : Int
|
||||
val <error>x</error> : Int
|
||||
}
|
||||
|
||||
class Y() {
|
||||
val x : Int
|
||||
val x : Int = 2
|
||||
}
|
||||
|
||||
class Y1 {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
get() = 1
|
||||
|
||||
class Test() {
|
||||
var a : Int
|
||||
var a : Int = 111
|
||||
var b : Int get() = <error>$a</error>; set(x) {a = x; <error>$a</error> = x}
|
||||
|
||||
this(i : Int) : this() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace redeclarations {
|
||||
object <error>A</error> {
|
||||
val x : Int
|
||||
val x : Int = 0
|
||||
|
||||
val A = 1
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
class Test() {
|
||||
<info>abstract</info> class Test() {
|
||||
<info>abstract</info> val x : Int
|
||||
<info>abstract</info> val x1 : Int <info>get</info>
|
||||
<info>abstract</info> val x2 : Int <info>get</info>() = 1
|
||||
<info>abstract</info> val x2 : Int <error><info>get</info>() = 1</error>
|
||||
|
||||
val <info>a</info> : Int
|
||||
val <info>b</info> : Int <info>get</info>
|
||||
val <error>a</error> : Int
|
||||
val <error>b</error> : Int <info>get</info>
|
||||
val <info>c</info> = 1
|
||||
|
||||
val <info>c1</info> = 1
|
||||
@@ -15,29 +15,30 @@ class Test() {
|
||||
<info>get</info>() { return 1 }
|
||||
val c4 : Int
|
||||
<info>get</info>() = 1
|
||||
val <info>c5</info> : Int
|
||||
val <error>c5</error> : Int
|
||||
<info>get</info>() = $c5 + 1
|
||||
|
||||
<info>abstract</info> var y : Int
|
||||
<info>abstract</info> var y1 : Int <info>get</info>
|
||||
<info>abstract</info> var y2 : Int <info>set</info>
|
||||
<info>abstract</info> var y3 : Int <info>set</info> <info>get</info>
|
||||
<info>abstract</info> var y4 : Int <info>set</info> <info>get</info>() = 1
|
||||
<info>abstract</info> var y5 : Int <info>set</info>(x) {} <info>get</info>() = 1
|
||||
<info>abstract</info> var y4 : Int <info>set</info> <error><info>get</info>() = 1</error>
|
||||
<info>abstract</info> var y5 : Int <error><info>set</info>(x) {}</error> <error><info>get</info>() = 1</error>
|
||||
<info>abstract</info> var y6 : Int <error><info>set</info>(x) {}</error>
|
||||
|
||||
var <info>v</info> : Int
|
||||
var <info>v1</info> : Int <info>get</info>
|
||||
var <info>v2</info> : Int <info>get</info> <info>set</info>
|
||||
var <info>v3</info> : Int <info>get</info>() = 1; <info>set</info>
|
||||
var <error>v</error> : Int
|
||||
var <error>v1</error> : Int <info>get</info>
|
||||
var <error>v2</error> : Int <info>get</info> <info>set</info>
|
||||
var <error>v3</error> : Int <info>get</info>() = 1; <info>set</info>
|
||||
var v4 : Int <info>get</info>() = 1; <info>set</info>(x){}
|
||||
|
||||
var <info>v5</info> : Int <info>get</info>() = 1; <info>set</info>(x){$v5 = x}
|
||||
var <info>v6</info> : Int <info>get</info>() = $v6 + 1; <info>set</info>(x){}
|
||||
var <error>v5</error> : Int <info>get</info>() = 1; <info>set</info>(x){$v5 = x}
|
||||
var <error>v6</error> : Int <info>get</info>() = $v6 + 1; <info>set</info>(x){}
|
||||
|
||||
val v7 : Int <info>abstract</info> <info>get</info>
|
||||
var v8 : Int <info>abstract</info> <info>get</info> <info>abstract</info> <info>set</info>
|
||||
var <info>v9</info> : Int <info>abstract</info> <info>set</info>
|
||||
var <info>v10</info> : Int <info>abstract</info> <info>get</info>
|
||||
var <error>v9</error> : Int <info>abstract</info> <info>set</info>
|
||||
var <error>v10</error> : Int <info>abstract</info> <info>get</info>
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
fun foo1() : fun (Int) : Int
|
||||
fun foo1() : fun (Int) : Int = { (x: Int) => x }
|
||||
|
||||
fun foo() {
|
||||
val h : fun (Int) : Int = foo1();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
enum class ProtocolState {
|
||||
abstract enum class ProtocolState {
|
||||
WAITING {
|
||||
override fun signal() = ProtocolState.TALKING
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
enum class ProtocolState {
|
||||
abstract enum class ProtocolState {
|
||||
WAITING {
|
||||
override fun signal() = ProtocolState.TALKING
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
class Item(val room: Object) {
|
||||
val name : String
|
||||
abstract class Item(val room: Object) {
|
||||
abstract val name : String
|
||||
}
|
||||
|
||||
val items: ArrayList<Item> = ArrayList<Item>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
abstract open class Default {
|
||||
fun defaultValue(): Int
|
||||
abstract fun defaultValue(): Int
|
||||
}
|
||||
|
||||
class MyInt() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class Base() {
|
||||
public var v : Int
|
||||
public var v : Int = 0
|
||||
}
|
||||
|
||||
class Left() : Base() {}
|
||||
|
||||
@@ -2,7 +2,7 @@ class C() {
|
||||
public var f: Int
|
||||
|
||||
{
|
||||
f = 610
|
||||
$f = 610
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ class Base() {
|
||||
public val read : Int
|
||||
get() = 239
|
||||
|
||||
public var readwrite : Int
|
||||
public var readwrite : Int = 0
|
||||
get() = $readwrite + 1
|
||||
set(n : Int) {
|
||||
$readwrite = n
|
||||
|
||||
@@ -72,7 +72,7 @@ public class ClassGenTest extends CodegenTestCase {
|
||||
}
|
||||
|
||||
public void testAbstractMethod() throws Exception {
|
||||
loadText("class Foo { abstract fun x(): String; fun y(): Int = 0 }");
|
||||
loadText("abstract class Foo { abstract fun x(): String; fun y(): Int = 0 }");
|
||||
|
||||
final ClassFileFactory codegens = generateClassesInFile();
|
||||
final Class aClass = loadClass("Foo", codegens);
|
||||
|
||||
@@ -125,7 +125,7 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
}
|
||||
|
||||
public void testAbstractVal() throws Exception {
|
||||
loadText("class Foo { public abstract val x: String }");
|
||||
loadText("abstract class Foo { public abstract val x: String }");
|
||||
final ClassFileFactory codegens = generateClassesInFile();
|
||||
final Class aClass = loadClass("Foo", codegens);
|
||||
assertNotNull(aClass.getMethod("getX"));
|
||||
|
||||
Reference in New Issue
Block a user