Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,12 @@ public void visitPropertyExpression(final PropertyExpression expression) {
boolean readOnly = !typeCheckingContext.isTargetOfEnclosingAssignment(expression);
if (existsProperty(expression, readOnly)
|| extension.handleUnresolvedProperty(expression)) {
if (readOnly) { // GROOVY-12305: record narrowed type of instanceof-guarded receiver for later use
ClassNode temporaryType = getInferredTypeFromTempInfo(expression, expression.getNodeMetaData(INFERRED_TYPE));
if (temporaryType != null && !isObjectType(temporaryType)) {
expression.putNodeMetaData(INFERRED_TYPE, temporaryType);
}
}
return; // resolved or excused
}
recordMissingProperty(expression);
Expand Down Expand Up @@ -7428,7 +7434,7 @@ protected List<ClassNode> getTemporaryTypesForExpression(final Expression expres
}

private ClassNode getInferredTypeFromTempInfo(final Expression expression, final ClassNode expressionType) {
if (expression instanceof VariableExpression && !isPrimitiveType(expressionType)) {
if ((expression instanceof VariableExpression || expression instanceof PropertyExpression) && !isPrimitiveType(expressionType)) {
List<ClassNode> tempTypes = getTemporaryTypesForExpression(expression);
if (!tempTypes.isEmpty()) {
ClassNode superclass;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1321,6 +1321,30 @@ class FieldsAndPropertiesSTCTest extends StaticTypeCheckingTestCase {
'''
}

// GROOVY-12305
@Test
void testMapPropertyAccess19() {
assertScript '''
def test(Map foo) {
foo.a instanceof Map ? foo.a.b : foo.a
}
assert test(a: [b: 'c']) == 'c'
assert test(a: 'x') == 'x'
'''

assertScript '''
def test(Map foo) {
if (foo.a instanceof Map) {
foo.a.b
} else {
foo.a
}
}
assert test(a: [b: 'c']) == 'c'
assert test(a: 'x') == 'x'
'''
}

@Test
void testTypeCheckerDoesNotThinkPropertyIsReadOnly() {
assertScript '''
Expand Down
Loading