add check for escaped identifiers
This commit is contained in:
@@ -565,6 +565,7 @@ public interface Errors {
|
||||
DiagnosticFactory1<JetSimpleNameExpression, JetType> COMPARE_TO_TYPE_MISMATCH = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<PsiElement> UNDERSCORE_IS_DEPRECATED = DiagnosticFactory0.create(WARNING);
|
||||
DiagnosticFactory1<PsiElement, String> INVALID_CHARACTERS = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<PsiElement> INAPPLICABLE_OPERATOR_MODIFIER = DiagnosticFactory0.create(WARNING);
|
||||
DiagnosticFactory0<PsiElement> INAPPLICABLE_INFIX_MODIFIER = DiagnosticFactory0.create(WARNING);
|
||||
|
||||
+1
@@ -377,6 +377,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(COMPARE_TO_TYPE_MISMATCH, "''compareTo()'' must return kotlin.Int, but returns {0}", RENDER_TYPE);
|
||||
|
||||
MAP.put(UNDERSCORE_IS_DEPRECATED, "Names _, __, ___, ..., are deprecated");
|
||||
MAP.put(INVALID_CHARACTERS, "Name {0}", STRING);
|
||||
|
||||
MAP.put(INAPPLICABLE_OPERATOR_MODIFIER, "'operator' modifier is inapplicable on this function");
|
||||
MAP.put(INAPPLICABLE_INFIX_MODIFIER, "'infix' modifier is inapplicable on this function");
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.psi.JetDeclaration
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.psi.JetDeclaration
|
||||
|
||||
public interface DeclarationChecker {
|
||||
|
||||
|
||||
@@ -48,16 +48,19 @@ public class DeclarationsChecker {
|
||||
@NotNull private final ModifiersChecker.ModifiersCheckingProcedure modifiersChecker;
|
||||
@NotNull private final DescriptorResolver descriptorResolver;
|
||||
@NotNull private final AnnotationChecker annotationChecker;
|
||||
@NotNull private final IdentifierChecker identifierChecker;
|
||||
|
||||
public DeclarationsChecker(
|
||||
@NotNull DescriptorResolver descriptorResolver,
|
||||
@NotNull ModifiersChecker modifiersChecker,
|
||||
@NotNull AnnotationChecker annotationChecker,
|
||||
@NotNull IdentifierChecker identifierChecker,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
this.descriptorResolver = descriptorResolver;
|
||||
this.modifiersChecker = modifiersChecker.withTrace(trace);
|
||||
this.annotationChecker = annotationChecker;
|
||||
this.identifierChecker = identifierChecker;
|
||||
this.trace = trace;
|
||||
}
|
||||
|
||||
@@ -88,6 +91,7 @@ public class DeclarationsChecker {
|
||||
checkPrimaryConstructor(classOrObject, classDescriptor);
|
||||
|
||||
modifiersChecker.checkModifiersForDeclaration(classOrObject, classDescriptor);
|
||||
identifierChecker.checkDeclaration(classOrObject, trace);
|
||||
checkClassExposedType(classOrObject, classDescriptor);
|
||||
}
|
||||
|
||||
@@ -98,6 +102,7 @@ public class DeclarationsChecker {
|
||||
|
||||
checkFunction(function, functionDescriptor);
|
||||
modifiersChecker.checkModifiersForDeclaration(function, functionDescriptor);
|
||||
identifierChecker.checkDeclaration(function, trace);
|
||||
}
|
||||
|
||||
Map<JetProperty, PropertyDescriptor> properties = bodiesResolveContext.getProperties();
|
||||
@@ -107,6 +112,7 @@ public class DeclarationsChecker {
|
||||
|
||||
checkProperty(property, propertyDescriptor);
|
||||
modifiersChecker.checkModifiersForDeclaration(property, propertyDescriptor);
|
||||
identifierChecker.checkDeclaration(property, trace);
|
||||
}
|
||||
|
||||
for (Map.Entry<JetSecondaryConstructor, ConstructorDescriptor> entry : bodiesResolveContext.getSecondaryConstructors().entrySet()) {
|
||||
@@ -119,6 +125,7 @@ public class DeclarationsChecker {
|
||||
|
||||
private void checkConstructorDeclaration(ConstructorDescriptor constructorDescriptor, JetDeclaration declaration) {
|
||||
modifiersChecker.checkModifiersForDeclaration(declaration, constructorDescriptor);
|
||||
identifierChecker.checkDeclaration(declaration, trace);
|
||||
}
|
||||
|
||||
private void checkModifiersAndAnnotationsInPackageDirective(JetFile file) {
|
||||
@@ -819,6 +826,7 @@ public class DeclarationsChecker {
|
||||
PropertyAccessorDescriptor propertyAccessorDescriptor = accessor.isGetter() ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter();
|
||||
assert propertyAccessorDescriptor != null : "No property accessor descriptor for " + property.getText();
|
||||
modifiersChecker.checkModifiersForDeclaration(accessor, propertyAccessorDescriptor);
|
||||
identifierChecker.checkDeclaration(accessor, trace);
|
||||
}
|
||||
checkAccessor(propertyDescriptor, property.getGetter(), propertyDescriptor.getGetter());
|
||||
checkAccessor(propertyDescriptor, property.getSetter(), propertyDescriptor.getSetter());
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.resolve
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.psi.JetDeclaration
|
||||
|
||||
public interface IdentifierChecker {
|
||||
fun checkIdentifier(identifier: PsiElement?, diagnosticHolder: DiagnosticSink)
|
||||
fun checkDeclaration(declaration: JetDeclaration, diagnosticHolder: DiagnosticSink)
|
||||
|
||||
object DEFAULT : IdentifierChecker {
|
||||
override fun checkIdentifier(identifier: PsiElement?, diagnosticHolder: DiagnosticSink) {}
|
||||
override fun checkDeclaration(declaration: JetDeclaration, diagnosticHolder: DiagnosticSink) {}
|
||||
}
|
||||
}
|
||||
@@ -47,9 +47,11 @@ public class LazyTopDownAnalyzer(
|
||||
private val topLevelDescriptorProvider: TopLevelDescriptorProvider,
|
||||
private val fileScopeProvider: FileScopeProvider,
|
||||
private val declarationScopeProvider: DeclarationScopeProvider,
|
||||
private val qualifiedExpressionResolver: QualifiedExpressionResolver
|
||||
private val qualifiedExpressionResolver: QualifiedExpressionResolver,
|
||||
private val identifierChecker: IdentifierChecker
|
||||
) {
|
||||
public fun analyzeDeclarations(topDownAnalysisMode: TopDownAnalysisMode, declarations: Collection<PsiElement>, outerDataFlowInfo: DataFlowInfo): TopDownAnalysisContext {
|
||||
|
||||
val c = TopDownAnalysisContext(topDownAnalysisMode, outerDataFlowInfo, declarationScopeProvider)
|
||||
|
||||
val topLevelFqNames = HashMultimap.create<FqName, JetElement>()
|
||||
@@ -93,6 +95,7 @@ public class LazyTopDownAnalyzer(
|
||||
}
|
||||
|
||||
override fun visitPackageDirective(directive: JetPackageDirective) {
|
||||
directive.packageNames.forEach { identifierChecker.checkIdentifier(it.getIdentifier(), trace) }
|
||||
qualifiedExpressionResolver.resolvePackageHeader(directive, moduleDescriptor, trace)
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ abstract class TargetPlatform(
|
||||
override val builtIns: KotlinBuiltIns
|
||||
get() = DefaultBuiltIns.Instance
|
||||
override val defaultModuleParameters = ModuleParameters.Empty
|
||||
override val platformConfigurator = PlatformConfigurator(DynamicTypesSettings(), listOf(), listOf(), listOf(), listOf(), listOf())
|
||||
override val platformConfigurator = PlatformConfigurator(DynamicTypesSettings(), listOf(), listOf(), listOf(), listOf(), listOf(), IdentifierChecker.DEFAULT)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,8 @@ open class PlatformConfigurator(
|
||||
additionalCallCheckers: List<CallChecker>,
|
||||
additionalTypeCheckers: List<AdditionalTypeChecker>,
|
||||
additionalSymbolUsageValidators: List<SymbolUsageValidator>,
|
||||
private val additionalAnnotationCheckers: List<AdditionalAnnotationChecker>
|
||||
private val additionalAnnotationCheckers: List<AdditionalAnnotationChecker>,
|
||||
private val identifierChecker: IdentifierChecker
|
||||
) {
|
||||
|
||||
private val declarationCheckers: List<DeclarationChecker> = DEFAULT_DECLARATION_CHECKERS + additionalDeclarationCheckers
|
||||
@@ -81,6 +82,7 @@ open class PlatformConfigurator(
|
||||
typeCheckers.forEach { useInstance(it) }
|
||||
useInstance(symbolUsageValidator)
|
||||
additionalAnnotationCheckers.forEach { useInstance(it) }
|
||||
useInstance(identifierChecker)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,8 @@ public class TypeResolver(
|
||||
private val storageManager: StorageManager,
|
||||
private val lazinessToken: TypeLazinessToken,
|
||||
private val dynamicTypesSettings: DynamicTypesSettings,
|
||||
private val dynamicCallableDescriptors: DynamicCallableDescriptors
|
||||
private val dynamicCallableDescriptors: DynamicCallableDescriptors,
|
||||
private val identifierChecker: IdentifierChecker
|
||||
) {
|
||||
|
||||
public open class FlexibleTypeCapabilitiesProvider {
|
||||
@@ -238,6 +239,7 @@ public class TypeResolver(
|
||||
|
||||
override fun visitFunctionType(type: JetFunctionType) {
|
||||
val receiverTypeRef = type.getReceiverTypeReference()
|
||||
type.parameters.forEach { identifierChecker.checkDeclaration(it, c.trace) }
|
||||
val receiverType = if (receiverTypeRef == null) null else resolveType(c.noBareTypes(), receiverTypeRef)
|
||||
|
||||
type.parameters.forEach { checkParameterInFunctionType(it) }
|
||||
|
||||
+3
@@ -393,6 +393,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
if (loopParameter != null) {
|
||||
VariableDescriptor variableDescriptor = createLoopParameterDescriptor(loopParameter, expectedParameterType, context);
|
||||
components.modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(loopParameter, variableDescriptor);
|
||||
components.identifierChecker.checkDeclaration(loopParameter, context.trace);
|
||||
|
||||
loopScope.addVariableDescriptor(variableDescriptor);
|
||||
}
|
||||
@@ -406,6 +407,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
loopScope, multiParameter, iteratorNextAsReceiver, loopRange, context
|
||||
);
|
||||
components.modifiersChecker.withTrace(context.trace).checkModifiersForMultiDeclaration(multiParameter);
|
||||
components.identifierChecker.checkDeclaration(multiParameter, context.trace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,6 +475,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
JetParameter catchParameter = catchClause.getCatchParameter();
|
||||
JetExpression catchBody = catchClause.getCatchBody();
|
||||
if (catchParameter != null) {
|
||||
components.identifierChecker.checkDeclaration(catchParameter, context.trace);
|
||||
ModifiersChecker.ModifiersCheckingProcedure modifiersChecking = components.modifiersChecker.withTrace(context.trace);
|
||||
modifiersChecking.checkParameterHasNoValOrVar(catchParameter, VAL_OR_VAR_ON_CATCH_PARAMETER);
|
||||
ModifierCheckerCore.INSTANCE$.check(catchParameter, context.trace, null);
|
||||
|
||||
+6
-1
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
|
||||
import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator;
|
||||
import org.jetbrains.kotlin.types.DynamicTypesSettings;
|
||||
import org.jetbrains.kotlin.types.TypeIntersector;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@@ -55,6 +54,7 @@ public class ExpressionTypingComponents {
|
||||
/*package*/ ModifiersChecker modifiersChecker;
|
||||
/*package*/ DataFlowAnalyzer dataFlowAnalyzer;
|
||||
/*package*/ Iterable<CallChecker> callCheckers;
|
||||
/*package*/ IdentifierChecker identifierChecker;
|
||||
|
||||
@Inject
|
||||
public void setGlobalContext(@NotNull GlobalContext globalContext) {
|
||||
@@ -161,6 +161,11 @@ public class ExpressionTypingComponents {
|
||||
this.modifiersChecker = modifiersChecker;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setIdentifierChecker(@NotNull IdentifierChecker identifierChecker) {
|
||||
this.identifierChecker = identifierChecker;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setDataFlowAnalyzer(@NotNull DataFlowAnalyzer dataFlowAnalyzer) {
|
||||
this.dataFlowAnalyzer = dataFlowAnalyzer;
|
||||
|
||||
+2
@@ -165,6 +165,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
|
||||
scope.addVariableDescriptor(propertyDescriptor);
|
||||
components.modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(property, propertyDescriptor);
|
||||
components.identifierChecker.checkDeclaration(property, context.trace);
|
||||
return typeInfo.replaceType(components.dataFlowAnalyzer.checkStatementType(property, context));
|
||||
}
|
||||
|
||||
@@ -185,6 +186,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
}
|
||||
components.multiDeclarationResolver.defineLocalVariablesFromMultiDeclaration(scope, multiDeclaration, expressionReceiver, initializer, context);
|
||||
components.modifiersChecker.withTrace(context.trace).checkModifiersForMultiDeclaration(multiDeclaration);
|
||||
components.identifierChecker.checkDeclaration(multiDeclaration, context.trace);
|
||||
return typeInfo.replaceType(components.dataFlowAnalyzer.checkStatementType(multiDeclaration, context));
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@ public class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Express
|
||||
)
|
||||
|
||||
components.modifiersChecker.withTrace(context.trace).checkModifiersForLocalDeclaration(function, functionDescriptor)
|
||||
components.identifierChecker.checkDeclaration(function, context.trace)
|
||||
if (!function.hasBody()) {
|
||||
context.trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor))
|
||||
}
|
||||
@@ -140,6 +141,7 @@ public class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Express
|
||||
val functionTypeExpected = !noExpectedType(expectedType) && KotlinBuiltIns.isFunctionOrExtensionFunctionType(expectedType)
|
||||
|
||||
val functionDescriptor = createFunctionLiteralDescriptor(expression, context)
|
||||
expression.valueParameters.forEach { components.identifierChecker.checkDeclaration(it, context.trace) }
|
||||
val safeReturnType = computeReturnType(expression, context, functionDescriptor, functionTypeExpected)
|
||||
functionDescriptor.setReturnType(safeReturnType)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user