diff --git a/examples/tests/current_test.panda b/examples/tests/current_test.panda index 45adc0b1e..994303ddb 100644 --- a/examples/tests/current_test.panda +++ b/examples/tests/current_test.panda @@ -237,7 +237,12 @@ internal class Test { // get test instance shared Test getTestField() { - return this.testField + if true { + return this.testField + } + else { + return null + } } } diff --git a/panda-framework/src/main/java/org/panda_lang/framework/language/architecture/statement/PandaCell.java b/panda-framework/src/main/java/org/panda_lang/framework/language/architecture/statement/PandaCell.java deleted file mode 100644 index 05f5d3f6f..000000000 --- a/panda-framework/src/main/java/org/panda_lang/framework/language/architecture/statement/PandaCell.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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.framework.language.architecture.statement; - -import org.panda_lang.framework.design.architecture.statement.Cell; -import org.panda_lang.framework.design.architecture.statement.Statement; - -public final class PandaCell implements Cell { - - private Statement statement; - private boolean manipulated; - - public PandaCell(Statement statement) { - this.statement = statement; - } - - @Override - public void setStatement(Statement statement) { - if (this.statement != null) { - this.manipulated = true; - } - - this.statement = statement; - } - - @Override - public boolean isManipulated() { - return manipulated; - } - - @Override - public Statement getStatement() { - return statement; - } - -} diff --git a/panda/src/main/java/org/panda_lang/panda/language/interpreter/parser/block/BlockParser.java b/panda/src/main/java/org/panda_lang/panda/language/interpreter/parser/block/BlockParser.java index de18e3381..9e805ccc4 100644 --- a/panda/src/main/java/org/panda_lang/panda/language/interpreter/parser/block/BlockParser.java +++ b/panda/src/main/java/org/panda_lang/panda/language/interpreter/parser/block/BlockParser.java @@ -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; @@ -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()); } } diff --git a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/prototype/MethodParser.java b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/prototype/MethodParser.java index 11b2b4d36..5869e1487 100644 --- a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/prototype/MethodParser.java +++ b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/prototype/MethodParser.java @@ -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; @@ -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; @@ -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()) @@ -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()); } } diff --git a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/LogParser.java b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/LogParser.java index db0978af8..e5bdff2a3 100644 --- a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/LogParser.java +++ b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/LogParser.java @@ -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 { @@ -55,11 +57,9 @@ protected BootstrapInitializer 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)); diff --git a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/StandaloneExpressionParser.java b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/StandaloneExpressionParser.java index 04148b381..b8ebbc0fa 100644 --- a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/StandaloneExpressionParser.java +++ b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/StandaloneExpressionParser.java @@ -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 { private static final ExpressionParserSettings SETTINGS = ExpressionParserSettings.create() .onlyStandalone() @@ -48,7 +48,7 @@ public final class StandaloneExpressionParser extends ParserBootstrap { private ExpressionParser expressionParser; @Override - protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) { + protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) { this.expressionParser = context.getComponent(Components.EXPRESSION); return initializer; } diff --git a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/TryCatchParser.java b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/TryCatchParser.java index c68a7fc67..da61a6a9c 100644 --- a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/TryCatchParser.java +++ b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/TryCatchParser.java @@ -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 { private static final ScopeParser SCOPE_PARSER = new ScopeParser(); @Override - protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) { + protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) { return initializer .handler(new TokenHandler(Keywords.TRY)) .interceptor(new LinearPatternInterceptor()) diff --git a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/BreakParser.java b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/BreakParser.java index e79b2b481..6bec071cf 100644 --- a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/BreakParser.java +++ b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/BreakParser.java @@ -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 { @Override - protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) { + protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) { return initializer .handler(new TokenHandler(Keywords.BREAK)) .interceptor(new LinearPatternInterceptor()) diff --git a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/ContinueParser.java b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/ContinueParser.java index f7a1554c2..c16f5a130 100644 --- a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/ContinueParser.java +++ b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/ContinueParser.java @@ -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 { @Override - protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) { + protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) { return initializer .handler(new TokenHandler(Keywords.CONTINUE)) .interceptor(new LinearPatternInterceptor()) diff --git a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/Return.java b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/Return.java index 778212f9c..1fc2ea0a0 100644 --- a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/Return.java +++ b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/Return.java @@ -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; diff --git a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/ReturnParser.java b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/ReturnParser.java index 32ff60f74..bf415fc89 100644 --- a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/ReturnParser.java +++ b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/ReturnParser.java @@ -34,10 +34,10 @@ 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 { @Override - protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) { + protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) { return initializer .handler(new TokenHandler(Keywords.RETURN)) .interceptor(new LinearPatternInterceptor()) @@ -45,8 +45,8 @@ protected BootstrapInitializer initialize(Context context, BootstrapInitializer } @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)); } } diff --git a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/Returnable.java b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/Returnable.java new file mode 100644 index 000000000..b4d9b00d0 --- /dev/null +++ b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/Returnable.java @@ -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 { + +} diff --git a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/Throw.java b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/Throw.java index 74ab0adc4..a72f3629f 100644 --- a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/Throw.java +++ b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/Throw.java @@ -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; diff --git a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/ThrowParser.java b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/ThrowParser.java index 98ab8d84f..3d9af783b 100644 --- a/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/ThrowParser.java +++ b/panda/src/main/java/org/panda_lang/panda/language/resource/syntax/scope/branching/ThrowParser.java @@ -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 { @Override - protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) { + protected BootstrapInitializer initialize(Context context, BootstrapInitializer initializer) { return initializer .handler(new TokenHandler(Keywords.THROW)) .interceptor(new LinearPatternInterceptor())