Skip to content

Commit

Permalink
GH-392 Make sure that method returns value
Browse files Browse the repository at this point in the history
  • Loading branch information
dzikoysk committed Mar 14, 2020
1 parent 619d6bf commit a140bba
Show file tree
Hide file tree
Showing 14 changed files with 66 additions and 82 deletions.
7 changes: 6 additions & 1 deletion examples/tests/current_test.panda
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,12 @@ internal class Test {

// get test instance
shared Test getTestField() {
return this.testField
if true {
return this.testField
}
else {
return null
}
}

}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
package org.panda_lang.panda.language.interpreter.parser.block;

import org.jetbrains.annotations.Nullable;
import org.panda_lang.framework.design.architecture.statement.Cell;
import org.panda_lang.framework.design.architecture.statement.Scope;
import org.panda_lang.framework.design.architecture.statement.Statement;
import org.panda_lang.framework.design.interpreter.parser.Components;
import org.panda_lang.framework.design.interpreter.parser.Context;
import org.panda_lang.framework.design.interpreter.parser.pipeline.Channel;
Expand Down Expand Up @@ -74,11 +74,11 @@ void parse(Context context, LocalData local, @Component Channel channel, @Compon
BlockSubparser blockParser = channel.get("result", BlockSubparser.class);
Context delegatedContext = local.allocated(context.fork()).withComponent(Components.CHANNEL, channel);

if (!parent.getCells().isEmpty()) {
Cell cell = parent.getCells().get(parent.getCells().size() - 1);
if (!parent.getStatements().isEmpty()) {
Statement statement = parent.getStatements().get(parent.getStatements().size() - 1);

if (cell.getStatement() instanceof BlockStatement) {
delegatedContext.withComponent(BlockComponents.PREVIOUS_BLOCK, ((BlockStatement) cell.getStatement()).getBlock());
if (statement instanceof BlockStatement) {
delegatedContext.withComponent(BlockComponents.PREVIOUS_BLOCK, ((BlockStatement) statement).getBlock());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.panda_lang.framework.design.interpreter.parser.pipeline.Pipelines;
import org.panda_lang.framework.design.interpreter.source.SourceLocation;
import org.panda_lang.framework.design.interpreter.token.Snippet;
import org.panda_lang.framework.design.interpreter.token.SnippetUtils;
import org.panda_lang.framework.design.interpreter.token.TokenRepresentation;
import org.panda_lang.framework.language.architecture.prototype.MethodScope;
import org.panda_lang.framework.language.architecture.prototype.PandaMethod;
Expand Down Expand Up @@ -59,6 +60,7 @@
import org.panda_lang.panda.language.interpreter.parser.context.handlers.CustomPatternHandler;
import org.panda_lang.panda.language.interpreter.parser.context.interceptors.CustomPatternInterceptor;
import org.panda_lang.panda.language.resource.syntax.PandaPriorities;
import org.panda_lang.panda.language.resource.syntax.scope.branching.Returnable;

import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -113,7 +115,7 @@ void parse(Context context, LocalData local, @Component Prototype prototype, @In
);
}

PandaMethod method = PandaMethod.builder()
PandaMethod method = local.allocated(PandaMethod.builder()
.prototype(prototype)
.parameters(parameters)
.name(name.getValue())
Expand All @@ -124,15 +126,19 @@ void parse(Context context, LocalData local, @Component Prototype prototype, @In
.isStatic(result.has("static"))
.isNative(existingMethod.isPresent() && existingMethod.get().isNative())
.methodBody(methodScope)
.build();
.build());

prototype.getMethods().declare(method);
}

@Autowired(order = 2, delegation = Delegation.NEXT_DEFAULT)
void parse(Context delegatedContext, @Local MethodScope methodScope, @Nullable @Src("body") Snippet body) throws Exception {
if (body != null) {
SCOPE_PARSER.parse(delegatedContext, methodScope, body);
void parse(Context context, @Local MethodScope methodScope, @Local PrototypeMethod method, @Nullable @Src("body") Snippet body) throws Exception {
if (!SnippetUtils.isEmpty(body)) {
SCOPE_PARSER.parse(context, methodScope, body);
}

if (!void.class.isAssignableFrom(method.getType().getAssociatedClass().getImplementation()) && !methodScope.hasEffective(Returnable.class)) {
throw new PandaParserFailure(context, "Missing return statement in method " + method.getPropertyName());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
import org.panda_lang.panda.language.interpreter.parser.context.handlers.TokenHandler;
import org.panda_lang.panda.language.interpreter.parser.context.interceptors.CustomPatternInterceptor;

import java.util.Arrays;

@RegistrableParser(pipeline = Pipelines.SCOPE_LABEL)
public final class LogParser extends ParserBootstrap<Object> {

Expand All @@ -55,11 +57,9 @@ protected BootstrapInitializer<Object> initialize(Context context, BootstrapInit

@Autowired
void parse(Context context, @Component ExpressionParser parser, @Component Scope scope, @Inter SourceLocation location, @Src("arguments") ExpressionTransaction[] transactions) {
Expression[] expressions = new Expression[transactions.length];

for (int index = 0; index < transactions.length; index++) {
expressions[index] = transactions[index].getExpression();
}
Expression[] expressions = Arrays.stream(transactions)
.map(ExpressionTransaction::getExpression)
.toArray(Expression[]::new);

Messenger messenger = context.getComponent(Components.ENVIRONMENT).getMessenger();
scope.addStatement(new LogStatement(location, messenger, expressions));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import org.panda_lang.panda.language.resource.syntax.PandaPriorities;

@RegistrableParser(pipeline = Pipelines.SCOPE_LABEL, priority = PandaPriorities.SCOPE_EXPRESSION)
public final class StandaloneExpressionParser extends ParserBootstrap {
public final class StandaloneExpressionParser extends ParserBootstrap<Object> {

private static final ExpressionParserSettings SETTINGS = ExpressionParserSettings.create()
.onlyStandalone()
Expand All @@ -48,7 +48,7 @@ public final class StandaloneExpressionParser extends ParserBootstrap {
private ExpressionParser expressionParser;

@Override
protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) {
protected BootstrapInitializer<Object> initialize(Context context, BootstrapInitializer<Object> initializer) {
this.expressionParser = context.getComponent(Components.EXPRESSION);
return initializer;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@
import org.panda_lang.panda.language.interpreter.parser.context.interceptors.LinearPatternInterceptor;

@RegistrableParser(pipeline = Pipelines.SCOPE_LABEL)
public final class TryCatchParser extends ParserBootstrap {
public final class TryCatchParser extends ParserBootstrap<Object> {

private static final ScopeParser SCOPE_PARSER = new ScopeParser();

@Override
protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) {
protected BootstrapInitializer<Object> initialize(Context context, BootstrapInitializer<Object> initializer) {
return initializer
.handler(new TokenHandler(Keywords.TRY))
.interceptor(new LinearPatternInterceptor())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
import org.panda_lang.panda.language.interpreter.parser.context.interceptors.LinearPatternInterceptor;

@RegistrableParser(pipeline = Pipelines.SCOPE_LABEL)
public final class BreakParser extends ParserBootstrap {
public final class BreakParser extends ParserBootstrap<Object> {

@Override
protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) {
protected BootstrapInitializer<Object> initialize(Context context, BootstrapInitializer<Object> initializer) {
return initializer
.handler(new TokenHandler(Keywords.BREAK))
.interceptor(new LinearPatternInterceptor())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
import org.panda_lang.panda.language.interpreter.parser.context.interceptors.LinearPatternInterceptor;

@RegistrableParser(pipeline = Pipelines.SCOPE_LABEL)
public final class ContinueParser extends ParserBootstrap {
public final class ContinueParser extends ParserBootstrap<Object> {

@Override
protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) {
protected BootstrapInitializer<Object> initialize(Context context, BootstrapInitializer<Object> initializer) {
return initializer
.handler(new TokenHandler(Keywords.CONTINUE))
.interceptor(new LinearPatternInterceptor())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import org.panda_lang.framework.design.runtime.Status;
import org.panda_lang.framework.language.architecture.dynamic.AbstractExecutableStatement;

final class Return extends AbstractExecutableStatement implements Controller {
final class Return extends AbstractExecutableStatement implements Returnable, Controller {

private final Expression value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,19 @@
import org.panda_lang.panda.language.interpreter.parser.context.interceptors.LinearPatternInterceptor;

@RegistrableParser(pipeline = Pipelines.SCOPE_LABEL)
public final class ReturnParser extends ParserBootstrap {
public final class ReturnParser extends ParserBootstrap<Object> {

@Override
protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) {
protected BootstrapInitializer<Object> initialize(Context context, BootstrapInitializer<Object> initializer) {
return initializer
.handler(new TokenHandler(Keywords.RETURN))
.interceptor(new LinearPatternInterceptor())
.pattern("return &value:*=expression");
}

@Autowired
void parse(@Component Scope block, @Inter SourceLocation location, @Src("value") @Nullable Expression value) {
block.addStatement(new Return(location, value));
void parse(@Component Scope scope, @Inter SourceLocation location, @Src("value") @Nullable Expression value) {
scope.addStatement(new Return(location, value));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2015-2019 Dzikoysk
*
* 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.panda_lang.panda.language.resource.syntax.scope.branching;

import org.panda_lang.framework.design.architecture.statement.Statement;

public interface Returnable extends Statement {

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import org.panda_lang.framework.language.architecture.dynamic.AbstractExecutableStatement;
import org.panda_lang.utilities.commons.UnsafeUtils;

final class Throw extends AbstractExecutableStatement implements Controller {
final class Throw extends AbstractExecutableStatement implements Returnable, Controller {

private final Expression value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@
import org.panda_lang.panda.language.interpreter.parser.context.interceptors.LinearPatternInterceptor;

@RegistrableParser(pipeline = Pipelines.SCOPE_LABEL)
public final class ThrowParser extends ParserBootstrap {
public final class ThrowParser extends ParserBootstrap<Object> {

@Override
protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) {
protected BootstrapInitializer<Object> initialize(Context context, BootstrapInitializer<Object> initializer) {
return initializer
.handler(new TokenHandler(Keywords.THROW))
.interceptor(new LinearPatternInterceptor())
Expand Down

0 comments on commit a140bba

Please sign in to comment.