|
1 | 1 | /*
|
2 |
| - * Copyright 2010-2016 JetBrains s.r.o. |
| 2 | + * Copyright 2010-2017 JetBrains s.r.o. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
@@ -37,46 +37,59 @@ object ConstModifierChecker : SimpleDeclarationChecker {
|
37 | 37 |
|
38 | 38 | val constModifierPsiElement = declaration.modifierList!!.getModifier(KtTokens.CONST_KEYWORD)!!
|
39 | 39 |
|
40 |
| - val diagnostic = checkCanBeConst(declaration, constModifierPsiElement, descriptor) |
| 40 | + val diagnostic = checkCanBeConst(declaration, constModifierPsiElement, descriptor).diagnostic |
41 | 41 | if (diagnostic != null) {
|
42 | 42 | diagnosticHolder.report(diagnostic)
|
43 | 43 | }
|
44 | 44 | }
|
45 | 45 |
|
46 |
| - fun checkCanBeConst(declaration: KtDeclaration, |
| 46 | + fun canBeConst(declaration: KtDeclaration, constModifierPsiElement: PsiElement, descriptor: VariableDescriptor): Boolean = |
| 47 | + checkCanBeConst(declaration, constModifierPsiElement, descriptor).canBeConst |
| 48 | + |
| 49 | + private fun checkCanBeConst(declaration: KtDeclaration, |
47 | 50 | constModifierPsiElement: PsiElement,
|
48 |
| - descriptor: VariableDescriptor): Diagnostic? { |
| 51 | + descriptor: VariableDescriptor): ConstApplicability { |
49 | 52 | if (descriptor.isVar) {
|
50 |
| - return Errors.WRONG_MODIFIER_TARGET.on(constModifierPsiElement, KtTokens.CONST_KEYWORD, "vars") |
| 53 | + return Errors.WRONG_MODIFIER_TARGET.on(constModifierPsiElement, KtTokens.CONST_KEYWORD, "vars").nonApplicable() |
51 | 54 | }
|
52 | 55 |
|
53 | 56 | val containingDeclaration = descriptor.containingDeclaration
|
54 | 57 | if (containingDeclaration is ClassDescriptor && containingDeclaration.kind != ClassKind.OBJECT) {
|
55 |
| - return Errors.CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT.on(constModifierPsiElement) |
| 58 | + return Errors.CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT.on(constModifierPsiElement).nonApplicable() |
56 | 59 | }
|
57 | 60 |
|
58 |
| - if (declaration !is KtProperty || descriptor !is PropertyDescriptor) return null |
| 61 | + if (declaration !is KtProperty || descriptor !is PropertyDescriptor) return ConstApplicability.NonApplicable() |
59 | 62 |
|
60 | 63 | if (declaration.hasDelegate()) {
|
61 |
| - return Errors.CONST_VAL_WITH_DELEGATE.on(declaration.delegate!!) |
| 64 | + return Errors.CONST_VAL_WITH_DELEGATE.on(declaration.delegate!!).nonApplicable() |
62 | 65 | }
|
63 | 66 |
|
64 | 67 | if (descriptor is PropertyDescriptor && !descriptor.getter!!.isDefault) {
|
65 |
| - return Errors.CONST_VAL_WITH_GETTER.on(declaration.getter!!) |
| 68 | + return Errors.CONST_VAL_WITH_GETTER.on(declaration.getter!!).nonApplicable() |
66 | 69 | }
|
67 | 70 |
|
| 71 | + if (descriptor.type.isError) return ConstApplicability.NonApplicable() |
| 72 | + |
| 73 | + // Report errors about const initializer only on property of resolved types |
68 | 74 | if (!descriptor.type.canBeUsedForConstVal()) {
|
69 |
| - return Errors.TYPE_CANT_BE_USED_FOR_CONST_VAL.on(constModifierPsiElement, descriptor.type) |
| 75 | + return Errors.TYPE_CANT_BE_USED_FOR_CONST_VAL.on(constModifierPsiElement, descriptor.type).nonApplicable() |
70 | 76 | }
|
71 | 77 |
|
72 | 78 | if (declaration.initializer == null) {
|
73 |
| - return Errors.CONST_VAL_WITHOUT_INITIALIZER.on(constModifierPsiElement) |
| 79 | + return Errors.CONST_VAL_WITHOUT_INITIALIZER.on(constModifierPsiElement).nonApplicable() |
74 | 80 | }
|
75 | 81 |
|
76 | 82 | if (descriptor.compileTimeInitializer == null) {
|
77 |
| - return Errors.CONST_VAL_WITH_NON_CONST_INITIALIZER.on(declaration.initializer!!) |
| 83 | + return Errors.CONST_VAL_WITH_NON_CONST_INITIALIZER.on(declaration.initializer!!).nonApplicable() |
78 | 84 | }
|
79 | 85 |
|
80 |
| - return null |
| 86 | + return ConstApplicability.Applicable |
81 | 87 | }
|
82 | 88 | }
|
| 89 | + |
| 90 | +sealed class ConstApplicability(val canBeConst: Boolean, val diagnostic: Diagnostic?) { |
| 91 | + object Applicable : ConstApplicability(true, null) |
| 92 | + class NonApplicable(diagnostic: Diagnostic? = null) : ConstApplicability(false, diagnostic) |
| 93 | +} |
| 94 | + |
| 95 | +private fun Diagnostic.nonApplicable() = ConstApplicability.NonApplicable(this) |
0 commit comments